objectmodel 4.3.0 → 4.4.0

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.
Files changed (59) hide show
  1. package/.eslintignore +8 -8
  2. package/.eslintrc.json +25 -25
  3. package/.travis.yml +2 -2
  4. package/LICENSE +22 -22
  5. package/README.md +67 -67
  6. package/build/{add-banner.cjs → add-banner.js} +13 -13
  7. package/build/bundle-entry.dev.js +2 -2
  8. package/build/bundle-entry.js +11 -11
  9. package/build/{update-docs.cjs → update-docs.js} +7 -5
  10. package/dist/object-model.cjs +466 -472
  11. package/dist/object-model.js +466 -472
  12. package/dist/object-model.js.map +1 -1
  13. package/dist/object-model.min.js +2 -2
  14. package/dist/object-model.min.js.map +1 -1
  15. package/index.html +1603 -1603
  16. package/package.json +20 -10
  17. package/rollup.config.js +13 -13
  18. package/src/array-model.d.ts +16 -0
  19. package/src/array-model.js +68 -68
  20. package/src/devtool-formatter.js +198 -198
  21. package/src/function-model.d.ts +24 -0
  22. package/src/function-model.js +58 -65
  23. package/src/helpers.js +43 -43
  24. package/src/index.js +4 -4
  25. package/src/list-model.js +43 -43
  26. package/src/map-model.d.ts +18 -0
  27. package/src/map-model.js +48 -48
  28. package/src/object-model.d.ts +74 -0
  29. package/src/object-model.js +4 -3
  30. package/src/set-model.d.ts +16 -0
  31. package/src/set-model.js +41 -41
  32. package/test/array-model.spec.cjs +291 -291
  33. package/test/array-model.test-d.ts +24 -0
  34. package/test/basic-model.spec.cjs +263 -263
  35. package/test/basic-model.test-d.ts +30 -0
  36. package/test/bench/array.html +51 -51
  37. package/test/bench/bench-lib.js +49 -49
  38. package/test/bench/map-no-cast.html +53 -53
  39. package/test/bench/map-set.html +52 -52
  40. package/test/bench/map.html +51 -51
  41. package/test/bench/object-models.html +87 -87
  42. package/test/function-model.spec.cjs +161 -162
  43. package/test/function-model.test-d.ts +18 -0
  44. package/test/index.cjs +13 -13
  45. package/test/index.html +27 -27
  46. package/test/map-model.spec.cjs +224 -224
  47. package/test/map-model.test-d.ts +21 -0
  48. package/test/model.spec.cjs +30 -30
  49. package/test/object-model.spec.cjs +1345 -1327
  50. package/test/object-model.test-d.ts +53 -0
  51. package/test/set-model.spec.cjs +213 -213
  52. package/test/set-model.test-d.ts +17 -0
  53. package/test/umd.html +25 -25
  54. package/types/definitions.d.ts +43 -0
  55. package/types/helpers.d.ts +4 -0
  56. package/types/index.d.ts +6 -128
  57. package/test/lib/qunit.css +0 -436
  58. package/test/lib/qunit.js +0 -6582
  59. package/tsconfig.json +0 -10
@@ -1,66 +1,59 @@
1
- import {
2
- _check, _original, Any, checkAssertions, checkDefinition, extendDefinition, extendModel,
3
- formatDefinition, initModel, Model, stackError, unstackErrors
4
- } from "./object-model.js"
5
- import { extend, is, isFunction } from "./helpers.js"
6
-
7
- export default function FunctionModel(...argsDef) {
8
- return initModel({ arguments: argsDef }, FunctionModel, Function, null, model => ({
9
- getPrototypeOf: () => model.prototype,
10
-
11
- get(fn, key) {
12
- return key === _original ? fn : fn[key]
13
- },
14
-
15
- apply(fn, ctx, args) {
16
- const def = model.definition
17
- const remainingArgDef = def.arguments.find(argDef => is(Any.remaining, argDef))
18
- const nbArgsToCheck = remainingArgDef ? Math.max(args.length, def.arguments.length - 1) : def.arguments.length
19
-
20
- for (let i = 0; i < nbArgsToCheck; i++) {
21
- const argDef = remainingArgDef && i >= def.arguments.length - 1 ? remainingArgDef.definition : def.arguments[i]
22
- args[i] = checkDefinition(args[i], argDef, `arguments[${i}]`, model.errors, [], true)
23
- }
24
-
25
- checkAssertions(args, model, "arguments")
26
-
27
- let result
28
- if (!model.errors.length) {
29
- result = Reflect.apply(fn, ctx, args)
30
- if ("return" in def)
31
- result = checkDefinition(result, def.return, "return value", model.errors, [], true)
32
- }
33
- unstackErrors(model)
34
- return result
35
- }
36
- }))
37
- }
38
-
39
- extend(FunctionModel, Model, {
40
- toString(stack = []) {
41
- let out = `Function(${this.definition.arguments.map(
42
- argDef => formatDefinition(argDef, [...stack])
43
- ).join(", ")})`
44
-
45
- if ("return" in this.definition) {
46
- out += " => " + formatDefinition(this.definition.return, stack)
47
- }
48
- return out
49
- },
50
-
51
- return(def) {
52
- this.definition.return = def
53
- return this
54
- },
55
-
56
- extend(newArgs, newReturns) {
57
- const args = this.definition.arguments,
58
- mixedArgs = newArgs.map((a, i) => extendDefinition(i in args ? args[i] : [], newArgs[i])),
59
- mixedReturns = extendDefinition(this.definition.return, newReturns)
60
- return extendModel(new FunctionModel(...mixedArgs).return(mixedReturns), this)
61
- },
62
-
63
- [_check](f, path, errors) {
64
- if (!isFunction(f)) stackError(errors, "Function", f, path)
65
- }
1
+ import {
2
+ _check, _original, Any, checkAssertions, checkDefinition, extendDefinition, extendModel,
3
+ formatDefinition, initModel, Model, stackError, unstackErrors
4
+ } from "./object-model.js"
5
+ import { extend, is, isFunction } from "./helpers.js"
6
+
7
+ export default function FunctionModel(...argsDef) {
8
+ return initModel({ arguments: argsDef }, FunctionModel, Function, null, model => ({
9
+ getPrototypeOf: () => model.prototype,
10
+
11
+ get(fn, key) {
12
+ return key === _original ? fn : fn[key]
13
+ },
14
+
15
+ apply(fn, ctx, args) {
16
+ const def = model.definition
17
+ const remainingArgDef = def.arguments.find(argDef => is(Any.remaining, argDef))
18
+ const nbArgsToCheck = remainingArgDef ? Math.max(args.length, def.arguments.length - 1) : def.arguments.length
19
+
20
+ for (let i = 0; i < nbArgsToCheck; i++) {
21
+ const argDef = remainingArgDef && i >= def.arguments.length - 1 ? remainingArgDef.definition : def.arguments[i]
22
+ args[i] = checkDefinition(args[i], argDef, `arguments[${i}]`, model.errors, [], true)
23
+ }
24
+
25
+ checkAssertions(args, model, "arguments")
26
+
27
+ let result
28
+ if (!model.errors.length) {
29
+ result = Reflect.apply(fn, ctx, args)
30
+ if ("return" in def)
31
+ result = checkDefinition(result, def.return, "return value", model.errors, [], true)
32
+ }
33
+ unstackErrors(model)
34
+ return result
35
+ }
36
+ }))
37
+ }
38
+
39
+ extend(FunctionModel, Model, {
40
+ toString(stack = []) {
41
+ let out = `Function(${this.definition.arguments.map(
42
+ argDef => formatDefinition(argDef, [...stack])
43
+ ).join(", ")})`
44
+
45
+ if ("return" in this.definition) {
46
+ out += " => " + formatDefinition(this.definition.return, stack)
47
+ }
48
+ return out
49
+ },
50
+
51
+ return(def) {
52
+ this.definition.return = def
53
+ return this
54
+ },
55
+
56
+ [_check](f, path, errors) {
57
+ if (!isFunction(f)) stackError(errors, "Function", f, path)
58
+ }
66
59
  })
package/src/helpers.js CHANGED
@@ -1,44 +1,44 @@
1
- export const
2
- ObjectProto = Object.prototype,
3
- bettertypeof = x => ObjectProto.toString.call(x).match(/\s([a-zA-Z]+)/)[1],
4
- getProto = Object.getPrototypeOf,
5
- setProto = Object.setPrototypeOf,
6
-
7
- has = (o, prop) => ObjectProto.hasOwnProperty.call(o, prop),
8
- is = (Constructor, obj) => obj instanceof Constructor,
9
- isFunction = f => typeof f === "function",
10
- isObject = o => o && typeof o === "object",
11
- isString = s => typeof s === "string",
12
- isPlainObject = o => isObject(o) && getProto(o) === ObjectProto,
13
- isIterable = x => x && isFunction(x[Symbol.iterator]),
14
-
15
- proxify = (val, traps) => new Proxy(val, traps),
16
-
17
- merge = (target, src = {}) => {
18
- for (let key in src) {
19
- if (isPlainObject(src[key])) {
20
- const o = {}
21
- merge(o, target[key])
22
- merge(o, src[key])
23
- target[key] = o
24
- } else {
25
- target[key] = src[key]
26
- }
27
- }
28
- return target
29
- },
30
-
31
- define = (obj, key, value, enumerable = false) => {
32
- Object.defineProperty(obj, key, { value, enumerable, writable: true, configurable: true })
33
- },
34
-
35
- extend = (child, parent, props) => {
36
- child.prototype = Object.assign(Object.create(parent.prototype, {
37
- constructor: {
38
- value: child,
39
- writable: true,
40
- configurable: true
41
- }
42
- }), props)
43
- setProto(child, parent)
1
+ export const
2
+ ObjectProto = Object.prototype,
3
+ bettertypeof = x => ObjectProto.toString.call(x).match(/\s([a-zA-Z]+)/)[1],
4
+ getProto = Object.getPrototypeOf,
5
+ setProto = Object.setPrototypeOf,
6
+
7
+ has = (o, prop) => ObjectProto.hasOwnProperty.call(o, prop),
8
+ is = (Constructor, obj) => obj instanceof Constructor,
9
+ isFunction = f => typeof f === "function",
10
+ isObject = o => o && typeof o === "object",
11
+ isString = s => typeof s === "string",
12
+ isPlainObject = o => isObject(o) && getProto(o) === ObjectProto,
13
+ isIterable = x => x && isFunction(x[Symbol.iterator]),
14
+
15
+ proxify = (val, traps) => new Proxy(val, traps),
16
+
17
+ merge = (target, src = {}) => {
18
+ for (let key in src) {
19
+ if (isPlainObject(src[key])) {
20
+ const o = {}
21
+ merge(o, target[key])
22
+ merge(o, src[key])
23
+ target[key] = o
24
+ } else {
25
+ target[key] = src[key]
26
+ }
27
+ }
28
+ return target
29
+ },
30
+
31
+ define = (obj, key, value, enumerable = false) => {
32
+ Object.defineProperty(obj, key, { value, enumerable, writable: true, configurable: true })
33
+ },
34
+
35
+ extend = (child, parent, props) => {
36
+ child.prototype = Object.assign(Object.create(parent.prototype, {
37
+ constructor: {
38
+ value: child,
39
+ writable: true,
40
+ configurable: true
41
+ }
42
+ }), props)
43
+ setProto(child, parent)
44
44
  }
package/src/index.js CHANGED
@@ -1,5 +1,5 @@
1
- export { Model, BasicModel, ObjectModel, Any } from "./object-model.js"
2
- export { default as ArrayModel } from "./array-model.js"
3
- export { default as FunctionModel } from "./function-model.js"
4
- export { default as MapModel } from "./map-model.js"
1
+ export { Model, BasicModel, ObjectModel, Any } from "./object-model.js"
2
+ export { default as ArrayModel } from "./array-model.js"
3
+ export { default as FunctionModel } from "./function-model.js"
4
+ export { default as MapModel } from "./map-model.js"
5
5
  export { default as SetModel } from "./set-model.js"
package/src/list-model.js CHANGED
@@ -1,44 +1,44 @@
1
-
2
- import { _original, checkAssertions, checkDefinition, initModel, unstackErrors } from "./object-model.js"
3
- import { has, isFunction, proxify } from "./helpers.js"
4
-
5
- export const initListModel = (base, constructor, def, init, clone, mutators, otherTraps) => {
6
-
7
- return initModel(def, constructor, base, init, model => Object.assign({
8
- getPrototypeOf: () => model.prototype,
9
- get(l, key) {
10
- if (key === _original) return l
11
-
12
- const val = l[key]
13
- return isFunction(val) ? proxify(val, {
14
- apply(fn, ctx, args) {
15
- if (has(mutators, key)) {
16
- // indexes of arguments to check def + cast
17
- const [begin, end = args.length - 1, getArgDef] = mutators[key]
18
- for (let i = begin; i <= end; i++) {
19
- const argDef = getArgDef ? getArgDef(i) : model.definition
20
- args[i] = checkDefinition(
21
- args[i],
22
- argDef,
23
- `${base.name}.${key} arguments[${i}]`,
24
- model.errors,
25
- [],
26
- true
27
- )
28
- }
29
-
30
- if (model.assertions.length > 0) {
31
- const testingClone = clone(l)
32
- fn.apply(testingClone, args)
33
- checkAssertions(testingClone, model, `after ${key} mutation`)
34
- }
35
-
36
- unstackErrors(model)
37
- }
38
-
39
- return fn.apply(l, args)
40
- }
41
- }) : val
42
- }
43
- }, otherTraps))
1
+
2
+ import { _original, checkAssertions, checkDefinition, initModel, unstackErrors } from "./object-model.js"
3
+ import { has, isFunction, proxify } from "./helpers.js"
4
+
5
+ export const initListModel = (base, constructor, def, init, clone, mutators, otherTraps) => {
6
+
7
+ return initModel(def, constructor, base, init, model => Object.assign({
8
+ getPrototypeOf: () => model.prototype,
9
+ get(l, key) {
10
+ if (key === _original) return l
11
+
12
+ const val = l[key]
13
+ return isFunction(val) ? proxify(val, {
14
+ apply(fn, ctx, args) {
15
+ if (has(mutators, key)) {
16
+ // indexes of arguments to check def + cast
17
+ const [begin, end = args.length - 1, getArgDef] = mutators[key]
18
+ for (let i = begin; i <= end; i++) {
19
+ const argDef = getArgDef ? getArgDef(i) : model.definition
20
+ args[i] = checkDefinition(
21
+ args[i],
22
+ argDef,
23
+ `${base.name}.${key} arguments[${i}]`,
24
+ model.errors,
25
+ [],
26
+ true
27
+ )
28
+ }
29
+
30
+ if (model.assertions.length > 0) {
31
+ const testingClone = clone(l)
32
+ fn.apply(testingClone, args)
33
+ checkAssertions(testingClone, model, `after ${key} mutation`)
34
+ }
35
+
36
+ unstackErrors(model)
37
+ }
38
+
39
+ return fn.apply(l, args)
40
+ }
41
+ }) : val
42
+ }
43
+ }, otherTraps))
44
44
  }
@@ -0,0 +1,18 @@
1
+ import { FromDefinition, ModelDefinition } from "../types/definitions";
2
+ import { Model } from "./object-model";
3
+
4
+ export interface MapModel<Key extends ModelDefinition, Value extends ModelDefinition> extends Model<{ key: Key, value: Value}> {
5
+ (iterable: Map<FromDefinition<Key>, FromDefinition<Value>> | Array<[FromDefinition<Key>, FromDefinition<Value>]>): Map<FromDefinition<Key>, FromDefinition<Value>>;
6
+ new(iterable: Map<FromDefinition<Key>, FromDefinition<Value>> | Array<[FromDefinition<Key>, FromDefinition<Value>]>): Map<FromDefinition<Key>, FromDefinition<Value>>;
7
+
8
+ definition: { key: Key, value: Value };
9
+
10
+ extend<Keys extends ModelDefinition[], Values extends ModelDefinition[]>(otherKeys: Keys, otherValues: Values): MapModel<[Key, ...Keys], [Value, ...Values]>
11
+ }
12
+
13
+ export interface MapModelConstructor {
14
+ <Key extends ModelDefinition, Value extends ModelDefinition>(keyDefinition: Key, valueDefinition: Value): MapModel<Key, Value>;
15
+ new<Key extends ModelDefinition, Value extends ModelDefinition>(keyDefinition: Key, valueDefinition: Value): MapModel<Key, Value>;
16
+ }
17
+
18
+ export const MapModel: MapModelConstructor;
package/src/map-model.js CHANGED
@@ -1,49 +1,49 @@
1
- import {
2
- _check, cast, checkAssertions, checkDefinition,
3
- extendDefinition, extendModel, format, formatDefinition, Model, stackError
4
- } from "./object-model.js"
5
- import { initListModel } from "./list-model.js"
6
- import { extend, is, isIterable } from "./helpers.js"
7
-
8
- export default function MapModel(initialKeyDefinition, initialValueDefinition) {
9
- const getDef = i => i === 0 ? model.definition.key : model.definition.value;
10
- const model = initListModel(
11
- Map,
12
- MapModel,
13
- { key: initialKeyDefinition, value: initialValueDefinition },
14
- it => isIterable(it) ? new Map([...it].map(pair => pair.map((x, i) => cast(x, getDef(i))))) : it,
15
- map => new Map(map),
16
- {
17
- "set": [0, 1, getDef],
18
- "delete": [],
19
- "clear": []
20
- }
21
- )
22
-
23
- return model
24
- }
25
-
26
- extend(MapModel, Model, {
27
- toString(stack) {
28
- return `Map of ${formatDefinition(this.definition.key, stack)} : ${formatDefinition(this.definition.value, stack)}`
29
- },
30
-
31
- [_check](map, path, errors, stack) {
32
- if (is(Map, map)) {
33
- path = path || "Map"
34
- for (let [key, value] of map) {
35
- checkDefinition(key, this.definition.key, `${path} key`, errors, stack)
36
- checkDefinition(value, this.definition.value, `${path}[${format(key)}]`, errors, stack)
37
- }
38
- } else stackError(errors, this, map, path)
39
-
40
- checkAssertions(map, this, path, errors)
41
- },
42
-
43
- extend(keyParts, valueParts) {
44
- return extendModel(new MapModel(
45
- extendDefinition(this.definition.key, keyParts),
46
- extendDefinition(this.definition.value, valueParts)
47
- ), this)
48
- }
1
+ import {
2
+ _check, cast, checkAssertions, checkDefinition,
3
+ extendDefinition, extendModel, format, formatDefinition, Model, stackError
4
+ } from "./object-model.js"
5
+ import { initListModel } from "./list-model.js"
6
+ import { extend, is, isIterable } from "./helpers.js"
7
+
8
+ export default function MapModel(initialKeyDefinition, initialValueDefinition) {
9
+ const getDef = i => i === 0 ? model.definition.key : model.definition.value;
10
+ const model = initListModel(
11
+ Map,
12
+ MapModel,
13
+ { key: initialKeyDefinition, value: initialValueDefinition },
14
+ it => isIterable(it) ? new Map([...it].map(pair => pair.map((x, i) => cast(x, getDef(i))))) : it,
15
+ map => new Map(map),
16
+ {
17
+ "set": [0, 1, getDef],
18
+ "delete": [],
19
+ "clear": []
20
+ }
21
+ )
22
+
23
+ return model
24
+ }
25
+
26
+ extend(MapModel, Model, {
27
+ toString(stack) {
28
+ return `Map of ${formatDefinition(this.definition.key, stack)} : ${formatDefinition(this.definition.value, stack)}`
29
+ },
30
+
31
+ [_check](map, path, errors, stack) {
32
+ if (is(Map, map)) {
33
+ path = path || "Map"
34
+ for (let [key, value] of map) {
35
+ checkDefinition(key, this.definition.key, `${path} key`, errors, stack)
36
+ checkDefinition(value, this.definition.value, `${path}[${format(key)}]`, errors, stack)
37
+ }
38
+ } else stackError(errors, this, map, path)
39
+
40
+ checkAssertions(map, this, path, errors)
41
+ },
42
+
43
+ extend(keyParts, valueParts) {
44
+ return extendModel(new MapModel(
45
+ extendDefinition(this.definition.key, keyParts),
46
+ extendDefinition(this.definition.value, valueParts)
47
+ ), this)
48
+ }
49
49
  })
@@ -0,0 +1,74 @@
1
+ import { ExtendObjectDefinition, FromDefinition, FromObjectModelDefinition, ModelDefinition, ObjectModelDefinition } from '../types/definitions';
2
+
3
+ export type Assertion = (variable: unknown) => boolean
4
+
5
+ export interface ModelError {
6
+ message: string;
7
+ expected: any;
8
+ received: any;
9
+ path: string;
10
+ }
11
+
12
+ export interface Model<D> {
13
+ definition: D;
14
+ assertions: Assertion[];
15
+ name: string;
16
+
17
+ conventionForConstant(variableName: string): boolean;
18
+ conventionForPrivate(variableName: string): boolean;
19
+
20
+ toString(stack?: any[]): string;
21
+
22
+ as(name: string): this;
23
+
24
+ defaultTo<Default>(defaultValue: Default): ModelWithDefault<D,Default>;
25
+
26
+ test(value: any, errorCollector?: (errors: ModelError[]) => void): boolean;
27
+
28
+ errorCollector(errors: ModelError[]): void;
29
+
30
+ assert(assertion: Assertion, description?: string | Function): this;
31
+
32
+ }
33
+
34
+ export interface ModelWithDefault<D,Default> extends Model<D> {
35
+ default: Default
36
+
37
+ (): Default
38
+ new(): Default
39
+ }
40
+
41
+ export interface ModelConstructor {
42
+ <D>(definition: D): D extends ObjectModelDefinition ? ObjectModel<D> : BasicModel<D>;
43
+ new<D>(definition: D): D extends ObjectModelDefinition ? ObjectModel<D> : BasicModel<D>;
44
+ CHECK_ONCE: symbol;
45
+ }
46
+
47
+ export interface BasicModel<D> extends Model<D> {
48
+ (value: FromDefinition<D>): FromDefinition<D>
49
+ new(value: FromDefinition<D>): FromDefinition<D>
50
+
51
+ extend<E extends ModelDefinition[]>(...extensions: E): BasicModel<E extends [] ? D : [D, ...E]>;
52
+ }
53
+
54
+ export interface BasicModelConstructor {
55
+ <D>(definition: D): BasicModel<D>
56
+ new<D>(definition: D): BasicModel<D>;
57
+ }
58
+
59
+ export interface ObjectModel<D extends ObjectModelDefinition> extends Model<D> {
60
+ (value: Partial<FromObjectModelDefinition<D>>): FromObjectModelDefinition<D>;
61
+ new(value: Partial<FromObjectModelDefinition<D>>): FromObjectModelDefinition<D>;
62
+
63
+ extend<Extensions extends (ObjectModelDefinition | ObjectModel<any>)[]>(...ext: Extensions) : ObjectModel<ExtendObjectDefinition<D, Extensions>>;
64
+ }
65
+
66
+ export interface ObjectModelConstructor {
67
+ <D extends ObjectModelDefinition>(definition: D): ObjectModel<D>;
68
+ new<D extends ObjectModelDefinition>(definition: D): ObjectModel<D>;
69
+ }
70
+
71
+ export const Any: any;
72
+ export const Model: ModelConstructor;
73
+ export const BasicModel: BasicModelConstructor;
74
+ export const ObjectModel: ObjectModelConstructor;
@@ -33,7 +33,8 @@ export const
33
33
  if (is(model, obj)) return obj
34
34
 
35
35
  if (!isObject(obj) && !isFunction(obj) && obj !== undefined) {
36
- stackError(model.errors, Object, obj)
36
+ // short circuit validation if not receiving an object as expected
37
+ return obj
37
38
  }
38
39
 
39
40
  merge(_this, model.default)
@@ -325,8 +326,8 @@ export const
325
326
  }
326
327
 
327
328
 
328
- export function Model(def, params) {
329
- return isPlainObject(def) ? new ObjectModel(def, params) : new BasicModel(def)
329
+ export function Model(def) {
330
+ return isPlainObject(def) ? new ObjectModel(def) : new BasicModel(def)
330
331
  }
331
332
 
332
333
  Object.assign(Model.prototype, {
@@ -0,0 +1,16 @@
1
+ import { FromDefinition, ModelDefinition } from "../types/definitions";
2
+ import { Model } from "./object-model";
3
+
4
+ export interface SetModel<D extends ModelDefinition> extends Model<D> {
5
+ (set: Set<FromDefinition<D>> | FromDefinition<D>[]): Set<FromDefinition<D>>;
6
+ new(set: Set<FromDefinition<D>> | FromDefinition<D>[]): Set<FromDefinition<D>>;
7
+
8
+ extend<E extends ModelDefinition[]>(...extensions: E): SetModel<E extends [] ? D : [D, ...E]>
9
+ }
10
+
11
+ export interface SetModelConstructor {
12
+ <D extends ModelDefinition>(itemDefinition: D): SetModel<D>;
13
+ new<D extends ModelDefinition>(itemDefinition: D): SetModel<D>;
14
+ }
15
+
16
+ export const SetModel: SetModelConstructor;
package/src/set-model.js CHANGED
@@ -1,42 +1,42 @@
1
- import {
2
- _check, cast, checkAssertions, checkDefinition,
3
- extendDefinition, extendModel, formatDefinition, Model, stackError
4
- } from "./object-model.js"
5
- import { initListModel } from "./list-model.js"
6
- import { extend, is, isIterable } from "./helpers.js"
7
-
8
- export default function SetModel(initialDefinition) {
9
- const model = initListModel(
10
- Set,
11
- SetModel,
12
- initialDefinition,
13
- it => isIterable(it) ? new Set([...it].map(val => cast(val, model.definition))) : it,
14
- set => new Set(set),
15
- {
16
- "add": [0, 0],
17
- "delete": [],
18
- "clear": []
19
- }
20
- )
21
-
22
- return model
23
- }
24
-
25
- extend(SetModel, Model, {
26
- toString(stack) {
27
- return "Set of " + formatDefinition(this.definition, stack)
28
- },
29
-
30
- [_check](set, path, errors, stack) {
31
- if (is(Set, set)) {
32
- for (let item of set.values()) {
33
- checkDefinition(item, this.definition, `${path || "Set"} value`, errors, stack)
34
- }
35
- } else stackError(errors, this, set, path)
36
- checkAssertions(set, this, path, errors)
37
- },
38
-
39
- extend(...newParts) {
40
- return extendModel(new SetModel(extendDefinition(this.definition, newParts)), this)
41
- }
1
+ import {
2
+ _check, cast, checkAssertions, checkDefinition,
3
+ extendDefinition, extendModel, formatDefinition, Model, stackError
4
+ } from "./object-model.js"
5
+ import { initListModel } from "./list-model.js"
6
+ import { extend, is, isIterable } from "./helpers.js"
7
+
8
+ export default function SetModel(initialDefinition) {
9
+ const model = initListModel(
10
+ Set,
11
+ SetModel,
12
+ initialDefinition,
13
+ it => isIterable(it) ? new Set([...it].map(val => cast(val, model.definition))) : it,
14
+ set => new Set(set),
15
+ {
16
+ "add": [0, 0],
17
+ "delete": [],
18
+ "clear": []
19
+ }
20
+ )
21
+
22
+ return model
23
+ }
24
+
25
+ extend(SetModel, Model, {
26
+ toString(stack) {
27
+ return "Set of " + formatDefinition(this.definition, stack)
28
+ },
29
+
30
+ [_check](set, path, errors, stack) {
31
+ if (is(Set, set)) {
32
+ for (let item of set.values()) {
33
+ checkDefinition(item, this.definition, `${path || "Set"} value`, errors, stack)
34
+ }
35
+ } else stackError(errors, this, set, path)
36
+ checkAssertions(set, this, path, errors)
37
+ },
38
+
39
+ extend(...newParts) {
40
+ return extendModel(new SetModel(extendDefinition(this.definition, newParts)), this)
41
+ }
42
42
  })