- Delete old Vite+Svelte frontend - Initialize new SvelteKit project with TypeScript - Configure Tailwind CSS v4 + DaisyUI - Implement JWT authentication with auto-refresh - Create login page with form validation (Zod) - Add protected route guards - Update Docker configuration for single-stage build - Add E2E tests with Playwright (6/11 passing) - Fix Svelte 5 reactivity with $state() runes Known issues: - 5 E2E tests failing (timing/async issues) - Token refresh implementation needs debugging - Validation error display timing
77 lines
2.7 KiB
JavaScript
77 lines
2.7 KiB
JavaScript
import { Callable, flatMorph, snapshot, throwParseError } from "@ark/util";
|
|
import { $ark } from "./shared/registry.js";
|
|
import { arkKind } from "./shared/utils.js";
|
|
export const parseGeneric = (paramDefs, bodyDef, $) => new GenericRoot(paramDefs, bodyDef, $, $, null);
|
|
export class LazyGenericBody extends Callable {
|
|
}
|
|
export class GenericRoot extends Callable {
|
|
[arkKind] = "generic";
|
|
paramDefs;
|
|
bodyDef;
|
|
$;
|
|
arg$;
|
|
baseInstantiation;
|
|
hkt;
|
|
description;
|
|
constructor(paramDefs, bodyDef, $, arg$, hkt) {
|
|
super((...args) => {
|
|
const argNodes = flatMorph(this.names, (i, name) => {
|
|
const arg = this.arg$.parse(args[i]);
|
|
if (!arg.extends(this.constraints[i])) {
|
|
throwParseError(writeUnsatisfiedParameterConstraintMessage(name, this.constraints[i].expression, arg.expression));
|
|
}
|
|
return [name, arg];
|
|
});
|
|
if (this.defIsLazy()) {
|
|
const def = this.bodyDef(argNodes);
|
|
return this.$.parse(def);
|
|
}
|
|
return this.$.parse(bodyDef, { args: argNodes });
|
|
});
|
|
this.paramDefs = paramDefs;
|
|
this.bodyDef = bodyDef;
|
|
this.$ = $;
|
|
this.arg$ = arg$;
|
|
this.hkt = hkt;
|
|
this.description =
|
|
hkt ?
|
|
(new hkt().description ?? `a generic type for ${hkt.constructor.name}`)
|
|
: "a generic type";
|
|
this.baseInstantiation = this(...this.constraints);
|
|
}
|
|
defIsLazy() {
|
|
return this.bodyDef instanceof LazyGenericBody;
|
|
}
|
|
cacheGetter(name, value) {
|
|
Object.defineProperty(this, name, { value });
|
|
return value;
|
|
}
|
|
get json() {
|
|
return this.cacheGetter("json", {
|
|
params: this.params.map(param => param[1].isUnknown() ? param[0] : [param[0], param[1].json]),
|
|
body: snapshot(this.bodyDef)
|
|
});
|
|
}
|
|
get params() {
|
|
return this.cacheGetter("params", this.paramDefs.map(param => typeof param === "string" ?
|
|
[param, $ark.intrinsic.unknown]
|
|
: [param[0], this.$.parse(param[1])]));
|
|
}
|
|
get names() {
|
|
return this.cacheGetter("names", this.params.map(e => e[0]));
|
|
}
|
|
get constraints() {
|
|
return this.cacheGetter("constraints", this.params.map(e => e[1]));
|
|
}
|
|
get internal() {
|
|
return this;
|
|
}
|
|
get referencesById() {
|
|
return this.baseInstantiation.internal.referencesById;
|
|
}
|
|
get references() {
|
|
return this.baseInstantiation.internal.references;
|
|
}
|
|
}
|
|
export const writeUnsatisfiedParameterConstraintMessage = (name, constraint, arg) => `${name} must be assignable to ${constraint} (was ${arg})`;
|