@gi-tcg/gts-runtime 0.4.4 → 0.4.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.ts CHANGED
@@ -57,76 +57,6 @@ declare class BindingContext {
57
57
  declare function createDefine(rootVM: IViewModel<any, any, any>, node: SingleAttributeNode): void;
58
58
  declare function createBinding(rootVM: IViewModel<any, any, any>, node: SingleAttributeNode): unknown[];
59
59
  //#endregion
60
- //#region ../../node_modules/@standard-schema/spec/dist/index.d.ts
61
- /** The Standard Typed interface. This is a base type extended by other specs. */
62
- interface StandardTypedV1<Input = unknown, Output = Input> {
63
- /** The Standard properties. */
64
- readonly "~standard": StandardTypedV1.Props<Input, Output>;
65
- }
66
- declare namespace StandardTypedV1 {
67
- /** The Standard Typed properties interface. */
68
- interface Props<Input = unknown, Output = Input> {
69
- /** The version number of the standard. */
70
- readonly version: 1;
71
- /** The vendor name of the schema library. */
72
- readonly vendor: string;
73
- /** Inferred types associated with the schema. */
74
- readonly types?: Types<Input, Output> | undefined;
75
- }
76
- /** The Standard Typed types interface. */
77
- interface Types<Input = unknown, Output = Input> {
78
- /** The input type of the schema. */
79
- readonly input: Input;
80
- /** The output type of the schema. */
81
- readonly output: Output;
82
- }
83
- /** Infers the input type of a Standard Typed. */
84
- type InferInput<Schema extends StandardTypedV1> = NonNullable<Schema["~standard"]["types"]>["input"];
85
- /** Infers the output type of a Standard Typed. */
86
- type InferOutput<Schema extends StandardTypedV1> = NonNullable<Schema["~standard"]["types"]>["output"];
87
- }
88
- /** The Standard Schema interface. */
89
- /** The Standard JSON Schema interface. */
90
- interface StandardJSONSchemaV1<Input = unknown, Output = Input> {
91
- /** The Standard JSON Schema properties. */
92
- readonly "~standard": StandardJSONSchemaV1.Props<Input, Output>;
93
- }
94
- declare namespace StandardJSONSchemaV1 {
95
- /** The Standard JSON Schema properties interface. */
96
- interface Props<Input = unknown, Output = Input> extends StandardTypedV1.Props<Input, Output> {
97
- /** Methods for generating the input/output JSON Schema. */
98
- readonly jsonSchema: StandardJSONSchemaV1.Converter;
99
- }
100
- /** The Standard JSON Schema converter interface. */
101
- interface Converter {
102
- /** Converts the input type to JSON Schema. May throw if conversion is not supported. */
103
- readonly input: (options: StandardJSONSchemaV1.Options) => Record<string, unknown>;
104
- /** Converts the output type to JSON Schema. May throw if conversion is not supported. */
105
- readonly output: (options: StandardJSONSchemaV1.Options) => Record<string, unknown>;
106
- }
107
- /**
108
- * The target version of the generated JSON Schema.
109
- *
110
- * It is *strongly recommended* that implementers support `"draft-2020-12"` and `"draft-07"`, as they are both in wide use. All other targets can be implemented on a best-effort basis. Libraries should throw if they don't support a specified target.
111
- *
112
- * The `"openapi-3.0"` target is intended as a standardized specifier for OpenAPI 3.0 which is a superset of JSON Schema `"draft-04"`.
113
- */
114
- type Target = "draft-2020-12" | "draft-07" | "openapi-3.0" | ({} & string);
115
- /** The options for the input/output methods. */
116
- interface Options {
117
- /** Specifies the target version of the generated JSON Schema. Support for all versions is on a best-effort basis. If a given version is not supported, the library should throw. */
118
- readonly target: Target;
119
- /** Explicit support for additional vendor-specific parameters, if needed. */
120
- readonly libraryOptions?: Record<string, unknown> | undefined;
121
- }
122
- /** The Standard types interface. */
123
- interface Types<Input = unknown, Output = Input> extends StandardTypedV1.Types<Input, Output> {}
124
- /** Infers the input type of a Standard. */
125
- type InferInput<Schema extends StandardTypedV1> = StandardTypedV1.InferInput<Schema>;
126
- /** Infers the output type of a Standard. */
127
- type InferOutput<Schema extends StandardTypedV1> = StandardTypedV1.InferOutput<Schema>;
128
- }
129
- //#endregion
130
60
  //#region src/view_model.d.ts
131
61
  interface AttributeBlockDefinition {
132
62
  "~action"?: AttributeDefinition | undefined;
@@ -199,14 +129,6 @@ declare class AttributeDefHelper<ModelT> {
199
129
  declare function defineViewModel<T, const BlockDef extends Partial<Record<string | Action, AttributeDefinition>>, CtorArgs extends any[] = [], InitMeta = void>(Ctor: new (...args: CtorArgs) => T, modelDefFn: (helper: AttributeDefHelper<T>) => BlockDef, initMeta?: InitMeta): IViewModel<T, BlockDef & {
200
130
  "~meta": InitMeta;
201
131
  }, CtorArgs>;
202
- type SimpleViewModel<T> = IViewModel<T, { [K in keyof T]-?: {
203
- (value: T[K]): AttributeReturn.Done;
204
- uniqueKey(): K;
205
- required(): {} extends Pick<T, K> ? false : true;
206
- } } & {
207
- "~meta": undefined;
208
- }, []>;
209
- declare function defineSimpleViewModel<const T extends StandardJSONSchemaV1>(schema: T): SimpleViewModel<StandardJSONSchemaV1.InferInput<T>>;
210
132
  interface AttributeDefinition {
211
133
  (...args: any[]): AttributePositionalReturnBase;
212
134
  as?(): any;
@@ -237,4 +159,109 @@ type AttributeBinder<Model, T extends AttributeDefinition> = (model: Model, posi
237
159
  "~meta": void;
238
160
  }>) => T["as"] extends (() => infer U) ? U : void;
239
161
  //#endregion
240
- export { type AttributeReturn as AR, type AttributeReturn, type Action, type AttributeDefinition, type IViewModel, type Meta, type NamedAttributesNode, type NamedDefinition, type Prelude, type SimpleViewModel, type SingleAttributeNode, type View, createBinding, createDefine, defineSimpleViewModel, defineViewModel };
162
+ //#region ../../node_modules/@standard-schema/spec/dist/index.d.ts
163
+ /** The Standard Typed interface. This is a base type extended by other specs. */
164
+ interface StandardTypedV1<Input = unknown, Output = Input> {
165
+ /** The Standard properties. */
166
+ readonly "~standard": StandardTypedV1.Props<Input, Output>;
167
+ }
168
+ declare namespace StandardTypedV1 {
169
+ /** The Standard Typed properties interface. */
170
+ interface Props<Input = unknown, Output = Input> {
171
+ /** The version number of the standard. */
172
+ readonly version: 1;
173
+ /** The vendor name of the schema library. */
174
+ readonly vendor: string;
175
+ /** Inferred types associated with the schema. */
176
+ readonly types?: Types<Input, Output> | undefined;
177
+ }
178
+ /** The Standard Typed types interface. */
179
+ interface Types<Input = unknown, Output = Input> {
180
+ /** The input type of the schema. */
181
+ readonly input: Input;
182
+ /** The output type of the schema. */
183
+ readonly output: Output;
184
+ }
185
+ /** Infers the input type of a Standard Typed. */
186
+ type InferInput<Schema extends StandardTypedV1> = NonNullable<Schema["~standard"]["types"]>["input"];
187
+ /** Infers the output type of a Standard Typed. */
188
+ type InferOutput<Schema extends StandardTypedV1> = NonNullable<Schema["~standard"]["types"]>["output"];
189
+ }
190
+ /** The Standard Schema interface. */
191
+ /** The Standard JSON Schema interface. */
192
+ interface StandardJSONSchemaV1<Input = unknown, Output = Input> {
193
+ /** The Standard JSON Schema properties. */
194
+ readonly "~standard": StandardJSONSchemaV1.Props<Input, Output>;
195
+ }
196
+ declare namespace StandardJSONSchemaV1 {
197
+ /** The Standard JSON Schema properties interface. */
198
+ interface Props<Input = unknown, Output = Input> extends StandardTypedV1.Props<Input, Output> {
199
+ /** Methods for generating the input/output JSON Schema. */
200
+ readonly jsonSchema: StandardJSONSchemaV1.Converter;
201
+ }
202
+ /** The Standard JSON Schema converter interface. */
203
+ interface Converter {
204
+ /** Converts the input type to JSON Schema. May throw if conversion is not supported. */
205
+ readonly input: (options: StandardJSONSchemaV1.Options) => Record<string, unknown>;
206
+ /** Converts the output type to JSON Schema. May throw if conversion is not supported. */
207
+ readonly output: (options: StandardJSONSchemaV1.Options) => Record<string, unknown>;
208
+ }
209
+ /**
210
+ * The target version of the generated JSON Schema.
211
+ *
212
+ * It is *strongly recommended* that implementers support `"draft-2020-12"` and `"draft-07"`, as they are both in wide use. All other targets can be implemented on a best-effort basis. Libraries should throw if they don't support a specified target.
213
+ *
214
+ * The `"openapi-3.0"` target is intended as a standardized specifier for OpenAPI 3.0 which is a superset of JSON Schema `"draft-04"`.
215
+ */
216
+ type Target = "draft-2020-12" | "draft-07" | "openapi-3.0" | ({} & string);
217
+ /** The options for the input/output methods. */
218
+ interface Options {
219
+ /** Specifies the target version of the generated JSON Schema. Support for all versions is on a best-effort basis. If a given version is not supported, the library should throw. */
220
+ readonly target: Target;
221
+ /** Explicit support for additional vendor-specific parameters, if needed. */
222
+ readonly libraryOptions?: Record<string, unknown> | undefined;
223
+ }
224
+ /** The Standard types interface. */
225
+ interface Types<Input = unknown, Output = Input> extends StandardTypedV1.Types<Input, Output> {}
226
+ /** Infers the input type of a Standard. */
227
+ type InferInput<Schema extends StandardTypedV1> = StandardTypedV1.InferInput<Schema>;
228
+ /** Infers the output type of a Standard. */
229
+ type InferOutput<Schema extends StandardTypedV1> = StandardTypedV1.InferOutput<Schema>;
230
+ }
231
+ //#endregion
232
+ //#region src/utilts.d.ts
233
+ type UnionToIntersection<U> = (U extends any ? (k: U) => void : never) extends ((k: infer I) => void) ? I : never;
234
+ type LastOf<T> = UnionToIntersection<T extends any ? () => T : never> extends (() => infer R) ? R : never;
235
+ type IsSingleton<T, L = LastOf<T>> = [T] extends [never] ? false : [Exclude<T, L>] extends [never] ? true : false;
236
+ //#endregion
237
+ //#region src/simple_view_model.d.ts
238
+ interface SimpleViewModelOptions {
239
+ /**
240
+ * Recursively parse nested objects as sub-view models.
241
+ */
242
+ recursive?: boolean;
243
+ /**
244
+ * Treat boolean-compatible properties as switches, i.e. the presence
245
+ * of the attribute without a value sets the property to `true`.
246
+ *
247
+ * Ignored if the `recursive` option is enabled and a object value is acceptable.
248
+ */
249
+ booleanSwitch?: boolean;
250
+ }
251
+ type ExtractObject<T> = T extends object ? T : never;
252
+ type SimpleViewModelAttribute<ValueT, Options extends SimpleViewModelOptions> = {
253
+ (value: ValueT): AttributeReturn.Done;
254
+ } & (Options["recursive"] extends true ? IsSingleton<ExtractObject<ValueT>> extends true ? {
255
+ (): AttributeReturn.With<SimpleViewModel<ExtractObject<ValueT>, Options>>;
256
+ } : Options["booleanSwitch"] extends true ? [true] extends [ValueT] ? {
257
+ (): AttributeReturn.Done;
258
+ } : {} : {} : {});
259
+ type SimpleViewModel<T, Options extends SimpleViewModelOptions = {}> = IViewModel<T, { [K in keyof T]-?: SimpleViewModelAttribute<T[K], Options> & {
260
+ uniqueKey(): K;
261
+ required(): {} extends Pick<T, K> ? false : true;
262
+ } } & {
263
+ "~meta": undefined;
264
+ }, []>;
265
+ declare function defineSimpleViewModel<const T extends StandardJSONSchemaV1, const Options extends SimpleViewModelOptions = {}>(schema: T, options?: Options): SimpleViewModel<StandardJSONSchemaV1.InferInput<T>, Options>;
266
+ //#endregion
267
+ export { type AttributeReturn as AR, type AttributeReturn, type Action, type AttributeDefinition, type IViewModel, type Meta, type NamedAttributesNode, type NamedDefinition, type Prelude, type SimpleViewModel, type SimpleViewModelOptions, type SingleAttributeNode, type View, createBinding, createDefine, defineSimpleViewModel, defineViewModel };
package/dist/index.js CHANGED
@@ -1,3 +1,4 @@
1
+ import { Ajv2020 } from "ajv/dist/2020.js";
1
2
  //#region src/view.ts
2
3
  var View = class {
3
4
  #phantom;
@@ -130,16 +131,59 @@ function defineViewModel(Ctor, modelDefFn, initMeta) {
130
131
  helper["~assignActions"](defResult);
131
132
  return vm;
132
133
  }
133
- function defineSimpleViewModel(schema) {
134
- const jsonSchema = schema["~standard"].jsonSchema.input({ target: "draft-2020-12" });
134
+ //#endregion
135
+ //#region src/simple_view_model.ts
136
+ const ajv = new Ajv2020({ strict: false });
137
+ function isBooleanCompatible(propSchema) {
138
+ try {
139
+ return ajv.compile(propSchema)(true);
140
+ } catch {
141
+ return false;
142
+ }
143
+ }
144
+ function extractObjectSchema(propSchema) {
145
+ if (propSchema.type === "object") return propSchema;
146
+ if (Array.isArray(propSchema.anyOf)) {
147
+ const objectBranches = propSchema.anyOf.filter((s) => s && typeof s === "object" && s.type === "object");
148
+ if (objectBranches.length === 1) return objectBranches[0];
149
+ }
150
+ return null;
151
+ }
152
+ function createSimpleViewModelFromJsonSchema(jsonSchema, options) {
135
153
  const vm = new ViewModel(class SimpleViewModel {});
136
154
  const helper = new AttributeDefHelper(vm);
137
155
  const defResult = {};
138
- for (const key of Object.keys(jsonSchema.properties ?? {})) defResult[key] = helper.simpleAttribute()(function(value) {
139
- this[key] = value;
140
- });
156
+ for (const key of Object.keys(jsonSchema.properties ?? {})) {
157
+ const propSchema = jsonSchema.properties[key];
158
+ if (!propSchema) continue;
159
+ defResult[key] = registerAttribute(helper, key, propSchema, options);
160
+ }
141
161
  helper["~assignActions"](defResult);
142
162
  return vm;
143
163
  }
164
+ function registerAttribute(helper, key, propSchema, options) {
165
+ let objectSchema = null;
166
+ if (options.recursive && (objectSchema = extractObjectSchema(propSchema))) {
167
+ const subVM = createSimpleViewModelFromJsonSchema(objectSchema, options);
168
+ return helper.attribute((model, positionals, named) => {
169
+ if (positionals.length > 0) model[key] = positionals[0];
170
+ else model[key] = subVM.parse(named);
171
+ });
172
+ }
173
+ if (options.booleanSwitch && isBooleanCompatible(propSchema)) return helper.simpleAttribute()(function(...args) {
174
+ this[key] = args.length > 0 ? args[0] : true;
175
+ });
176
+ return helper.simpleAttribute()(function(value) {
177
+ this[key] = value;
178
+ });
179
+ }
180
+ function defineSimpleViewModel(schema, options) {
181
+ const resolvedOptions = {
182
+ booleanSwitch: false,
183
+ recursive: false,
184
+ ...options
185
+ };
186
+ return createSimpleViewModelFromJsonSchema(schema["~standard"].jsonSchema.input({ target: "draft-2020-12" }), resolvedOptions);
187
+ }
144
188
  //#endregion
145
189
  export { createBinding, createDefine, defineSimpleViewModel, defineViewModel };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gi-tcg/gts-runtime",
3
- "version": "0.4.4",
3
+ "version": "0.4.6",
4
4
  "repository": {
5
5
  "type": "git",
6
6
  "url": "https://github.com/piovium/gts.git"
@@ -18,12 +18,15 @@
18
18
  "src",
19
19
  "dist"
20
20
  ],
21
- "dependencies": {},
21
+ "dependencies": {
22
+ "ajv": "^8.20.0"
23
+ },
22
24
  "devDependencies": {
23
25
  "@standard-schema/spec": "^1.1.0",
24
26
  "json-schema-typed": "^8.0.2"
25
27
  },
26
28
  "scripts": {
27
- "build": "tsdown --platform neutral"
29
+ "build": "tsdown --platform neutral",
30
+ "test": "vitest"
28
31
  }
29
32
  }
package/src/index.ts CHANGED
@@ -1,10 +1,13 @@
1
1
  export {
2
2
  defineViewModel,
3
- defineSimpleViewModel,
4
3
  type AttributeDefinition,
5
4
  type IViewModel,
6
- type SimpleViewModel,
7
5
  } from "./view_model.ts";
6
+ export {
7
+ defineSimpleViewModel,
8
+ type SimpleViewModel,
9
+ type SimpleViewModelOptions,
10
+ } from "./simple_view_model.ts";
8
11
  export type { AttributeReturn, AR } from "./attribute_return.ts";
9
12
  export type { Action, Prelude, Meta, NamedDefinition } from "./symbols.ts";
10
13
 
@@ -0,0 +1,160 @@
1
+ import type { StandardJSONSchemaV1 } from "@standard-schema/spec";
2
+ import {
3
+ AttributeDefHelper,
4
+ ViewModel,
5
+ type IViewModel,
6
+ type AttributeAction,
7
+ } from "./view_model.ts";
8
+ import type { AttributeReturn } from "./attribute_return.ts";
9
+ import { Ajv2020 } from "ajv/dist/2020.js";
10
+ import type { IsSingleton } from "./utilts.ts";
11
+
12
+ export interface SimpleViewModelOptions {
13
+ /**
14
+ * Recursively parse nested objects as sub-view models.
15
+ */
16
+ recursive?: boolean;
17
+ /**
18
+ * Treat boolean-compatible properties as switches, i.e. the presence
19
+ * of the attribute without a value sets the property to `true`.
20
+ *
21
+ * Ignored if the `recursive` option is enabled and a object value is acceptable.
22
+ */
23
+ booleanSwitch?: boolean;
24
+ }
25
+
26
+ type ExtractObject<T> = T extends object ? T : never;
27
+
28
+ type SimpleViewModelAttribute<
29
+ ValueT,
30
+ Options extends SimpleViewModelOptions,
31
+ > = {
32
+ (value: ValueT): AttributeReturn.Done;
33
+ } & (Options["recursive"] extends true
34
+ ? IsSingleton<ExtractObject<ValueT>> extends true
35
+ ? {
36
+ (): AttributeReturn.With<
37
+ SimpleViewModel<ExtractObject<ValueT>, Options>
38
+ >;
39
+ }
40
+ : Options["booleanSwitch"] extends true
41
+ ? [true] extends [ValueT]
42
+ ? { (): AttributeReturn.Done }
43
+ : {}
44
+ : {}
45
+ : {});
46
+
47
+ export type SimpleViewModel<
48
+ T,
49
+ Options extends SimpleViewModelOptions = {},
50
+ > = IViewModel<
51
+ T,
52
+ {
53
+ [K in keyof T]-?: SimpleViewModelAttribute<T[K], Options> & {
54
+ uniqueKey(): K;
55
+ required(): {} extends Pick<T, K> ? false : true;
56
+ };
57
+ } & {
58
+ "~meta": undefined;
59
+ },
60
+ []
61
+ >;
62
+
63
+ const ajv = new Ajv2020({ strict: false });
64
+
65
+ function isBooleanCompatible(propSchema: Record<string, unknown>): boolean {
66
+ try {
67
+ const validate = ajv.compile(propSchema);
68
+ return validate(true);
69
+ } catch {
70
+ return false;
71
+ }
72
+ }
73
+
74
+ function extractObjectSchema(
75
+ propSchema: Record<string, unknown>,
76
+ ): Record<string, unknown> | null {
77
+ if (propSchema.type === "object") {
78
+ return propSchema;
79
+ }
80
+ if (Array.isArray(propSchema.anyOf)) {
81
+ const objectBranches = propSchema.anyOf.filter(
82
+ (s: any) => s && typeof s === "object" && s.type === "object",
83
+ );
84
+ if (objectBranches.length === 1) {
85
+ return objectBranches[0] as Record<string, unknown>;
86
+ }
87
+ }
88
+ return null;
89
+ }
90
+
91
+ function createSimpleViewModelFromJsonSchema(
92
+ jsonSchema: Record<string, unknown>,
93
+ options: SimpleViewModelOptions,
94
+ ): IViewModel<any, any, []> {
95
+ const Ctor = class SimpleViewModel {};
96
+ const vm = new ViewModel<any, any, []>(Ctor);
97
+ const helper = new AttributeDefHelper(vm);
98
+ const defResult: Record<string, any> = {};
99
+ for (const key of Object.keys(jsonSchema.properties ?? {})) {
100
+ const propSchema = (jsonSchema.properties as Record<string, unknown>)[key];
101
+ if (!propSchema) {
102
+ continue;
103
+ }
104
+ defResult[key] = registerAttribute(
105
+ helper,
106
+ key,
107
+ propSchema as Record<string, unknown>,
108
+ options,
109
+ );
110
+ }
111
+ helper["~assignActions"](defResult);
112
+ return vm as any;
113
+ }
114
+
115
+ function registerAttribute(
116
+ helper: AttributeDefHelper<any>,
117
+ key: string,
118
+ propSchema: Record<string, unknown>,
119
+ options: SimpleViewModelOptions,
120
+ ): unknown {
121
+ let objectSchema: Record<string, unknown> | null = null;
122
+ if (options.recursive && (objectSchema = extractObjectSchema(propSchema))) {
123
+ const subVM = createSimpleViewModelFromJsonSchema(objectSchema, options);
124
+ return helper.attribute((model, positionals, named) => {
125
+ if (positionals.length > 0) {
126
+ model[key] = positionals[0];
127
+ } else {
128
+ model[key] = subVM.parse(named);
129
+ }
130
+ });
131
+ }
132
+
133
+ if (options.booleanSwitch && isBooleanCompatible(propSchema)) {
134
+ return helper.simpleAttribute()(function (this: any, ...args: any[]) {
135
+ this[key] = args.length > 0 ? args[0] : true;
136
+ });
137
+ }
138
+
139
+ return helper.simpleAttribute()(function (this: any, value) {
140
+ this[key] = value;
141
+ });
142
+ }
143
+
144
+ export function defineSimpleViewModel<
145
+ const T extends StandardJSONSchemaV1,
146
+ const Options extends SimpleViewModelOptions = {},
147
+ >(
148
+ schema: T,
149
+ options?: Options,
150
+ ): SimpleViewModel<StandardJSONSchemaV1.InferInput<T>, Options> {
151
+ const resolvedOptions: SimpleViewModelOptions = {
152
+ booleanSwitch: false,
153
+ recursive: false,
154
+ ...options,
155
+ };
156
+ const jsonSchema = schema["~standard"].jsonSchema.input({
157
+ target: "draft-2020-12",
158
+ });
159
+ return createSimpleViewModelFromJsonSchema(jsonSchema, resolvedOptions);
160
+ }
package/src/utilts.ts ADDED
@@ -0,0 +1,26 @@
1
+ // we just write this time by time.
2
+ // we know this is not a good way to write typescript, but thats the only way to achieve our goal
3
+
4
+ type UnionToIntersection<U> = (U extends any ? (k: U) => void : never) extends (
5
+ k: infer I,
6
+ ) => void
7
+ ? I
8
+ : never;
9
+
10
+ type LastOf<T> =
11
+ UnionToIntersection<T extends any ? () => T : never> extends () => infer R
12
+ ? R
13
+ : never;
14
+
15
+ type Push<T extends any[], V> = [...T, V];
16
+ export type TuplifyUnion<
17
+ T,
18
+ L = LastOf<T>,
19
+ N = [T] extends [never] ? true : false,
20
+ > = true extends N ? [] : Push<TuplifyUnion<Exclude<T, L>>, L>;
21
+
22
+ export type IsSingleton<T, L = LastOf<T>> = [T] extends [never]
23
+ ? false
24
+ : [Exclude<T, L>] extends [never]
25
+ ? true
26
+ : false;
package/src/view_model.ts CHANGED
@@ -1,7 +1,6 @@
1
1
  import type { AttributeReturn } from "./attribute_return.ts";
2
2
  import type { Action, Meta, NamedDefinition } from "./symbols.ts";
3
3
  import { View } from "./view.ts";
4
- import type { StandardJSONSchemaV1 } from "@standard-schema/spec";
5
4
 
6
5
  export interface AttributeBlockDefinition {
7
6
  "~action"?: AttributeDefinition | undefined;
@@ -55,7 +54,7 @@ type LazyAttributeActionOrBinder<ModelT> = (
55
54
  named: View<any>,
56
55
  ) => unknown;
57
56
 
58
- class ViewModel<
57
+ export class ViewModel<
59
58
  ModelT,
60
59
  BlockDef extends AttributeBlockDefinition,
61
60
  CtorArgs extends any[],
@@ -154,7 +153,7 @@ type WithSimpleOptions<Base, Options extends SimpleAttributeOptions> = Base &
154
153
  ? { uniqueKey(): Options["uniqueKey"] }
155
154
  : {});
156
155
 
157
- class AttributeDefHelper<ModelT> {
156
+ export class AttributeDefHelper<ModelT> {
158
157
  #viewModel: ViewModel<ModelT, any, any>;
159
158
  constructor(viewModel: ViewModel<ModelT, any, any>) {
160
159
  this.#viewModel = viewModel;
@@ -296,37 +295,6 @@ export function defineViewModel<
296
295
  return vm;
297
296
  }
298
297
 
299
- export type SimpleViewModel<T> = IViewModel<
300
- T,
301
- {
302
- [K in keyof T]-?: {
303
- (value: T[K]): AttributeReturn.Done;
304
- uniqueKey(): K;
305
- required(): {} extends Pick<T, K> ? false : true;
306
- };
307
- } & { "~meta": undefined },
308
- []
309
- >;
310
-
311
- export function defineSimpleViewModel<const T extends StandardJSONSchemaV1>(
312
- schema: T,
313
- ): SimpleViewModel<StandardJSONSchemaV1.InferInput<T>> {
314
- const jsonSchema = schema["~standard"].jsonSchema.input({
315
- target: "draft-2020-12",
316
- });
317
- const Ctor = class SimpleViewModel {};
318
- const vm = new ViewModel<any, any, []>(Ctor);
319
- const helper = new AttributeDefHelper(vm);
320
- const defResult: Record<string, any> = {};
321
- for (const key of Object.keys(jsonSchema.properties ?? {})) {
322
- defResult[key] = helper.simpleAttribute()(function (this: any, value) {
323
- this[key] = value;
324
- });
325
- }
326
- helper["~assignActions"](defResult);
327
- return vm as any;
328
- }
329
-
330
298
  export interface AttributeDefinition {
331
299
  (...args: any[]): AttributePositionalReturnBase;
332
300
  as?(): any;