@nexigen/entity-normalizer 0.1.1 → 0.1.3

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 (187) hide show
  1. package/dist/async/async-duck.d.ts +38 -0
  2. package/dist/async/async-duck.js +189 -0
  3. package/dist/async/async-duck.js.map +1 -0
  4. package/dist/async/create-duck.d.ts +2 -0
  5. package/dist/async/create-duck.js +6 -0
  6. package/dist/async/create-duck.js.map +1 -0
  7. package/dist/async/index.d.ts +1 -0
  8. package/dist/async/index.js +2 -0
  9. package/dist/async/index.js.map +1 -0
  10. package/dist/async/marker.d.ts +1 -0
  11. package/dist/async/marker.js +2 -0
  12. package/dist/async/marker.js.map +1 -0
  13. package/dist/async/public.d.ts +34 -0
  14. package/dist/async/public.js +2 -0
  15. package/dist/async/public.js.map +1 -0
  16. package/dist/async/retry.d.ts +3 -0
  17. package/dist/async/retry.js +36 -0
  18. package/dist/async/retry.js.map +1 -0
  19. package/dist/async/types.d.ts +24 -0
  20. package/dist/async/types.js +2 -0
  21. package/dist/async/types.js.map +1 -0
  22. package/dist/constants/time.d.ts +6 -0
  23. package/dist/constants/time.js +7 -0
  24. package/dist/constants/time.js.map +1 -0
  25. package/dist/constants/values.d.ts +1 -0
  26. package/dist/constants/values.js +2 -0
  27. package/dist/constants/values.js.map +1 -0
  28. package/dist/create/cleaner.d.ts +7 -0
  29. package/dist/create/cleaner.js +69 -0
  30. package/dist/create/cleaner.js.map +1 -0
  31. package/dist/create/create-store.d.ts +2 -0
  32. package/dist/create/create-store.js +5 -0
  33. package/dist/create/create-store.js.map +1 -0
  34. package/dist/create/extractor.d.ts +8 -0
  35. package/dist/create/extractor.js +64 -0
  36. package/dist/create/extractor.js.map +1 -0
  37. package/dist/create/index.d.ts +1 -0
  38. package/dist/create/index.js +2 -0
  39. package/dist/create/index.js.map +1 -0
  40. package/dist/create/manager.d.ts +9 -0
  41. package/dist/create/manager.js +39 -0
  42. package/dist/create/manager.js.map +1 -0
  43. package/dist/create/proxy.d.ts +11 -0
  44. package/dist/create/proxy.js +57 -0
  45. package/dist/create/proxy.js.map +1 -0
  46. package/dist/create/scanner.d.ts +19 -0
  47. package/dist/create/scanner.js +109 -0
  48. package/dist/create/scanner.js.map +1 -0
  49. package/dist/create/utils.d.ts +3 -0
  50. package/dist/create/utils.js +33 -0
  51. package/dist/create/utils.js.map +1 -0
  52. package/dist/create-store-hooks.d.ts +19 -0
  53. package/dist/create-store-hooks.js +23 -0
  54. package/dist/create-store-hooks.js.map +1 -0
  55. package/dist/di/index.d.ts +2 -0
  56. package/dist/di/index.js +3 -0
  57. package/dist/di/index.js.map +1 -0
  58. package/dist/di/register-root-store.d.ts +11 -0
  59. package/dist/di/register-root-store.js +23 -0
  60. package/dist/di/register-root-store.js.map +1 -0
  61. package/dist/entities/cleaner/bucket.d.ts +8 -0
  62. package/dist/entities/cleaner/bucket.js +31 -0
  63. package/dist/entities/cleaner/bucket.js.map +1 -0
  64. package/dist/entities/cleaner/index.d.ts +1 -0
  65. package/dist/entities/cleaner/index.js +2 -0
  66. package/dist/entities/cleaner/index.js.map +1 -0
  67. package/dist/entities/cleaner/store.d.ts +12 -0
  68. package/dist/entities/cleaner/store.js +73 -0
  69. package/dist/entities/cleaner/store.js.map +1 -0
  70. package/dist/entities/cleaner/walker.d.ts +6 -0
  71. package/dist/entities/cleaner/walker.js +34 -0
  72. package/dist/entities/cleaner/walker.js.map +1 -0
  73. package/dist/entities/collection/create-entity-collection.d.ts +9 -0
  74. package/dist/entities/collection/create-entity-collection.js +17 -0
  75. package/dist/entities/collection/create-entity-collection.js.map +1 -0
  76. package/dist/entities/collection/entity-collection.d.ts +49 -0
  77. package/dist/entities/collection/entity-collection.js +186 -0
  78. package/dist/entities/collection/entity-collection.js.map +1 -0
  79. package/dist/entities/collection/index.d.ts +3 -0
  80. package/dist/entities/collection/index.js +2 -0
  81. package/dist/entities/collection/index.js.map +1 -0
  82. package/dist/entities/collection/marker.d.ts +2 -0
  83. package/dist/entities/collection/marker.js +3 -0
  84. package/dist/entities/collection/marker.js.map +1 -0
  85. package/dist/entities/collection/multi-entity-collection.d.ts +24 -0
  86. package/dist/entities/collection/multi-entity-collection.js +95 -0
  87. package/dist/entities/collection/multi-entity-collection.js.map +1 -0
  88. package/dist/entities/collection/public.d.ts +50 -0
  89. package/dist/entities/collection/public.js +2 -0
  90. package/dist/entities/collection/public.js.map +1 -0
  91. package/dist/entities/collection/types.d.ts +39 -0
  92. package/dist/entities/collection/types.js +2 -0
  93. package/dist/entities/collection/types.js.map +1 -0
  94. package/dist/entities/constants.d.ts +4 -0
  95. package/dist/entities/constants.js +5 -0
  96. package/dist/entities/constants.js.map +1 -0
  97. package/dist/entities/create-entity-schema.d.ts +2 -0
  98. package/dist/entities/create-entity-schema.js +5 -0
  99. package/dist/entities/create-entity-schema.js.map +1 -0
  100. package/dist/entities/index.d.ts +4 -0
  101. package/dist/entities/index.js +5 -0
  102. package/dist/entities/index.js.map +1 -0
  103. package/dist/entities/normalize.d.ts +11 -0
  104. package/dist/entities/normalize.js +79 -0
  105. package/dist/entities/normalize.js.map +1 -0
  106. package/dist/entities/processor.d.ts +14 -0
  107. package/dist/entities/processor.js +156 -0
  108. package/dist/entities/processor.js.map +1 -0
  109. package/dist/entities/public.d.ts +102 -0
  110. package/dist/entities/public.js +7 -0
  111. package/dist/entities/public.js.map +1 -0
  112. package/dist/entities/record/create-entity-record.d.ts +15 -0
  113. package/dist/entities/record/create-entity-record.js +13 -0
  114. package/dist/entities/record/create-entity-record.js.map +1 -0
  115. package/dist/entities/record/entity-record.d.ts +37 -0
  116. package/dist/entities/record/entity-record.js +83 -0
  117. package/dist/entities/record/entity-record.js.map +1 -0
  118. package/dist/entities/record/index.d.ts +2 -0
  119. package/dist/entities/record/index.js +2 -0
  120. package/dist/entities/record/index.js.map +1 -0
  121. package/dist/entities/record/marker.d.ts +1 -0
  122. package/dist/entities/record/marker.js +2 -0
  123. package/dist/entities/record/marker.js.map +1 -0
  124. package/dist/entities/record/public.d.ts +25 -0
  125. package/dist/entities/record/public.js +2 -0
  126. package/dist/entities/record/public.js.map +1 -0
  127. package/dist/entities/record/types.d.ts +3 -0
  128. package/dist/entities/record/types.js +2 -0
  129. package/dist/entities/record/types.js.map +1 -0
  130. package/dist/entities/schema.d.ts +12 -0
  131. package/dist/entities/schema.js +31 -0
  132. package/dist/entities/schema.js.map +1 -0
  133. package/dist/entities/store.d.ts +22 -0
  134. package/dist/entities/store.js +154 -0
  135. package/dist/entities/store.js.map +1 -0
  136. package/dist/entities/types.d.ts +82 -0
  137. package/dist/entities/types.js +2 -0
  138. package/dist/entities/types.js.map +1 -0
  139. package/dist/index.d.ts +12 -0
  140. package/dist/index.js +13 -0
  141. package/dist/index.js.map +1 -0
  142. package/dist/root/RootStore.d.ts +24 -0
  143. package/dist/root/RootStore.js +134 -0
  144. package/dist/root/RootStore.js.map +1 -0
  145. package/dist/root/coreApi/create-core-api.d.ts +7 -0
  146. package/dist/root/coreApi/create-core-api.js +12 -0
  147. package/dist/root/coreApi/create-core-api.js.map +1 -0
  148. package/dist/root/coreApi/entities.d.ts +10 -0
  149. package/dist/root/coreApi/entities.js +57 -0
  150. package/dist/root/coreApi/entities.js.map +1 -0
  151. package/dist/root/coreApi/lifecycle.d.ts +5 -0
  152. package/dist/root/coreApi/lifecycle.js +9 -0
  153. package/dist/root/coreApi/lifecycle.js.map +1 -0
  154. package/dist/root/coreApi/public.d.ts +71 -0
  155. package/dist/root/coreApi/public.js +6 -0
  156. package/dist/root/coreApi/public.js.map +1 -0
  157. package/dist/root/coreApi/stores.d.ts +2 -0
  158. package/dist/root/coreApi/stores.js +31 -0
  159. package/dist/root/coreApi/stores.js.map +1 -0
  160. package/dist/root/coreApi/types.d.ts +68 -0
  161. package/dist/root/coreApi/types.js +2 -0
  162. package/dist/root/coreApi/types.js.map +1 -0
  163. package/dist/root/create-root-store.d.ts +3 -0
  164. package/dist/root/create-root-store.js +11 -0
  165. package/dist/root/create-root-store.js.map +1 -0
  166. package/dist/root/fallback.d.ts +2 -0
  167. package/dist/root/fallback.js +6 -0
  168. package/dist/root/fallback.js.map +1 -0
  169. package/dist/root/index.d.ts +3 -0
  170. package/dist/root/index.js +3 -0
  171. package/dist/root/index.js.map +1 -0
  172. package/dist/root/marker.d.ts +1 -0
  173. package/dist/root/marker.js +2 -0
  174. package/dist/root/marker.js.map +1 -0
  175. package/dist/root/public.d.ts +28 -0
  176. package/dist/root/public.js +2 -0
  177. package/dist/root/public.js.map +1 -0
  178. package/dist/root/types.d.ts +66 -0
  179. package/dist/root/types.js +2 -0
  180. package/dist/root/types.js.map +1 -0
  181. package/dist/utils/index.d.ts +1 -0
  182. package/dist/utils/index.js +2 -0
  183. package/dist/utils/index.js.map +1 -0
  184. package/dist/utils/throttle-by-time.d.ts +1 -0
  185. package/dist/utils/throttle-by-time.js +11 -0
  186. package/dist/utils/throttle-by-time.js.map +1 -0
  187. package/package.json +11 -2
@@ -0,0 +1,39 @@
1
+ import { Cleaner } from './cleaner';
2
+ import { StoreSnapshotExtractor } from './extractor';
3
+ import { StoreProxy } from './proxy';
4
+ import { Scanner } from './scanner';
5
+ import { defineHiddenProp } from './utils';
6
+ const SUPPRESS_KEY = '__suppressPersistNotify';
7
+ function incSuppress(store) {
8
+ store[SUPPRESS_KEY] = (store[SUPPRESS_KEY] ?? 0) + 1;
9
+ }
10
+ function decSuppress(store) {
11
+ store[SUPPRESS_KEY] = Math.max(0, (store[SUPPRESS_KEY] ?? 0) - 1);
12
+ }
13
+ export class StoreManager {
14
+ constructor(deps) {
15
+ this.deps = deps;
16
+ this.scanner = new Scanner();
17
+ this.cleaner = new Cleaner(deps.system);
18
+ this.extractor = new StoreSnapshotExtractor(this.scanner);
19
+ }
20
+ create(StoreClass) {
21
+ const instance = new StoreClass(this.deps.domain);
22
+ const shape = this.scanner.scan(instance);
23
+ // reset
24
+ this.cleaner.applyReset(instance, shape);
25
+ // snapshot API (hidden)
26
+ defineHiddenProp(instance, '__getSnapshot', () => this.extractor.getSnapshot(instance, shape));
27
+ defineHiddenProp(instance, '__applySnapshot', (snap) => {
28
+ // suppress persist spam while mutating many fields
29
+ incSuppress(instance);
30
+ this.extractor.applySnapshot(instance, snap, shape);
31
+ decSuppress(instance);
32
+ // one notify after restore
33
+ queueMicrotask(() => this.deps.system?.getPersistence?.()?.onStoreStateChanged?.());
34
+ });
35
+ // proxy for action wrapping + coalesced notify
36
+ return new StoreProxy(this.deps.system, instance, shape.actions).build();
37
+ }
38
+ }
39
+ //# sourceMappingURL=manager.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"manager.js","sourceRoot":"","sources":["../../src/create/manager.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,sBAAsB,EAAE,MAAM,aAAa,CAAC;AACrD,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,EAAE,OAAO,EAAmB,MAAM,WAAW,CAAC;AACrD,OAAO,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAC;AAI3C,MAAM,YAAY,GAAG,yBAAyB,CAAC;AAE/C,SAAS,WAAW,CAAC,KAAU;IAC7B,KAAK,CAAC,YAAY,CAAC,GAAG,CAAC,KAAK,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC;AACvD,CAAC;AACD,SAAS,WAAW,CAAC,KAAU;IAC7B,KAAK,CAAC,YAAY,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;AACpE,CAAC;AAED,MAAM,OAAO,YAAY;IAKvB,YAAoB,IAAuB;QAAvB,SAAI,GAAJ,IAAI,CAAmB;QAJnC,YAAO,GAAG,IAAI,OAAO,EAAE,CAAC;QAK9B,IAAI,CAAC,OAAO,GAAG,IAAI,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QACxC,IAAI,CAAC,SAAS,GAAG,IAAI,sBAAsB,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IAC5D,CAAC;IAED,MAAM,CAAS,UAA4C;QACzD,MAAM,QAAQ,GAAG,IAAI,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QAClD,MAAM,KAAK,GAAe,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QAEtD,QAAQ;QACR,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAC;QAEzC,wBAAwB;QACxB,gBAAgB,CAAC,QAAe,EAAE,eAAe,EAAE,GAAG,EAAE,CACtD,IAAI,CAAC,SAAS,CAAC,WAAW,CAAC,QAAQ,EAAE,KAAK,CAAC,CAC5C,CAAC;QAEF,gBAAgB,CAAC,QAAe,EAAE,iBAAiB,EAAE,CAAC,IAAS,EAAE,EAAE;YACjE,mDAAmD;YACnD,WAAW,CAAC,QAAQ,CAAC,CAAC;YACtB,IAAI,CAAC,SAAS,CAAC,aAAa,CAAC,QAAQ,EAAE,IAAI,EAAE,KAAK,CAAC,CAAC;YACpD,WAAW,CAAC,QAAQ,CAAC,CAAC;YAEtB,2BAA2B;YAC3B,cAAc,CAAC,GAAG,EAAE,CAClB,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,cAAc,EAAE,EAAE,EAAE,mBAAmB,EAAE,EAAE,CAC9D,CAAC;QACJ,CAAC,CAAC,CAAC;QAEH,+CAA+C;QAC/C,OAAO,IAAI,UAAU,CACnB,IAAI,CAAC,IAAI,CAAC,MAAM,EAChB,QAAQ,EACR,KAAK,CAAC,OAAO,CACd,CAAC,KAAK,EAAY,CAAC;IACtB,CAAC;CACF"}
@@ -0,0 +1,11 @@
1
+ import type { SystemDeps } from '../root/types';
2
+ export declare class StoreProxy {
3
+ private deps;
4
+ private target;
5
+ private actions;
6
+ private notifyQueued;
7
+ constructor(deps: SystemDeps, target: any, actions: string[]);
8
+ build(): any;
9
+ private scheduleNotify;
10
+ private wrapAction;
11
+ }
@@ -0,0 +1,57 @@
1
+ import { runInAction } from 'mobx';
2
+ const SUPPRESS_KEY = '__suppressPersistNotify';
3
+ export class StoreProxy {
4
+ constructor(deps, target, actions) {
5
+ this.deps = deps;
6
+ this.target = target;
7
+ this.actions = actions;
8
+ this.notifyQueued = false;
9
+ }
10
+ build() {
11
+ return new Proxy(this.target, {
12
+ get: (target, prop, receiver) => {
13
+ const value = Reflect.get(target, prop, receiver);
14
+ if (!this.actions.includes(prop)) {
15
+ return value;
16
+ }
17
+ // allow duck/collection objects to pass-through (no wrapping)
18
+ if (value && typeof value === 'object') {
19
+ return value;
20
+ }
21
+ if (typeof value === 'function') {
22
+ return this.wrapAction(target, value);
23
+ }
24
+ return value;
25
+ },
26
+ set: (target, prop, val, receiver) => {
27
+ const result = Reflect.set(target, prop, val, receiver);
28
+ this.scheduleNotify(target);
29
+ return result;
30
+ },
31
+ });
32
+ }
33
+ scheduleNotify(target) {
34
+ if ((target?.[SUPPRESS_KEY] ?? 0) > 0) {
35
+ return;
36
+ }
37
+ if (this.notifyQueued) {
38
+ return;
39
+ }
40
+ this.notifyQueued = true;
41
+ queueMicrotask(() => {
42
+ this.notifyQueued = false;
43
+ this.deps.getPersistence?.()?.onStoreStateChanged?.();
44
+ });
45
+ }
46
+ wrapAction(target, fn) {
47
+ return (...args) => {
48
+ const result = runInAction(() => fn.apply(target, args));
49
+ if (result instanceof Promise) {
50
+ return result.finally(() => this.scheduleNotify(target));
51
+ }
52
+ this.scheduleNotify(target);
53
+ return result;
54
+ };
55
+ }
56
+ }
57
+ //# sourceMappingURL=proxy.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"proxy.js","sourceRoot":"","sources":["../../src/create/proxy.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,MAAM,CAAC;AAInC,MAAM,YAAY,GAAG,yBAAyB,CAAC;AAE/C,MAAM,OAAO,UAAU;IAGrB,YACU,IAAgB,EAChB,MAAW,EACX,OAAiB;QAFjB,SAAI,GAAJ,IAAI,CAAY;QAChB,WAAM,GAAN,MAAM,CAAK;QACX,YAAO,GAAP,OAAO,CAAU;QALnB,iBAAY,GAAG,KAAK,CAAC;IAM1B,CAAC;IAEJ,KAAK;QACH,OAAO,IAAI,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE;YAC5B,GAAG,EAAE,CAAC,MAAM,EAAE,IAAI,EAAE,QAAQ,EAAE,EAAE;gBAC9B,MAAM,KAAK,GAAG,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,IAAI,EAAE,QAAQ,CAAC,CAAC;gBAElD,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,IAAc,CAAC,EAAE,CAAC;oBAC3C,OAAO,KAAK,CAAC;gBACf,CAAC;gBAED,8DAA8D;gBAC9D,IAAI,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;oBACvC,OAAO,KAAK,CAAC;gBACf,CAAC;gBAED,IAAI,OAAO,KAAK,KAAK,UAAU,EAAE,CAAC;oBAChC,OAAO,IAAI,CAAC,UAAU,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;gBACxC,CAAC;gBAED,OAAO,KAAK,CAAC;YACf,CAAC;YAED,GAAG,EAAE,CAAC,MAAM,EAAE,IAAI,EAAE,GAAG,EAAE,QAAQ,EAAE,EAAE;gBACnC,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,IAAI,EAAE,GAAG,EAAE,QAAQ,CAAC,CAAC;gBACxD,IAAI,CAAC,cAAc,CAAC,MAAM,CAAC,CAAC;gBAC5B,OAAO,MAAM,CAAC;YAChB,CAAC;SACF,CAAC,CAAC;IACL,CAAC;IAEO,cAAc,CAAC,MAAW;QAChC,IAAI,CAAC,MAAM,EAAE,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC;YACtC,OAAO;QACT,CAAC;QAED,IAAI,IAAI,CAAC,YAAY,EAAE,CAAC;YACtB,OAAO;QACT,CAAC;QACD,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC;QAEzB,cAAc,CAAC,GAAG,EAAE;YAClB,IAAI,CAAC,YAAY,GAAG,KAAK,CAAC;YAC1B,IAAI,CAAC,IAAI,CAAC,cAAc,EAAE,EAAE,EAAE,mBAAmB,EAAE,EAAE,CAAC;QACxD,CAAC,CAAC,CAAC;IACL,CAAC;IAEO,UAAU,CAAC,MAAW,EAAE,EAAY;QAC1C,OAAO,CAAC,GAAG,IAAW,EAAE,EAAE;YACxB,MAAM,MAAM,GAAG,WAAW,CAAC,GAAG,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC,CAAC;YAEzD,IAAI,MAAM,YAAY,OAAO,EAAE,CAAC;gBAC9B,OAAO,MAAM,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,cAAc,CAAC,MAAM,CAAC,CAAC,CAAC;YAC3D,CAAC;YAED,IAAI,CAAC,cAAc,CAAC,MAAM,CAAC,CAAC;YAC5B,OAAO,MAAM,CAAC;QAChB,CAAC,CAAC;IACJ,CAAC;CACF"}
@@ -0,0 +1,19 @@
1
+ export type StoreShape = {
2
+ plain: Record<string, any>;
3
+ single: string[];
4
+ multi: string[];
5
+ records: string[];
6
+ actions: string[];
7
+ };
8
+ export declare class Scanner {
9
+ private isDuck;
10
+ private isSingleCollection;
11
+ private isMultiCollection;
12
+ private isRecord;
13
+ scanPlain(store: any): Record<string, any>;
14
+ scanSingleKeys(store: any): string[];
15
+ scanMultiKeys(store: any): string[];
16
+ scanRecordKeys(store: any): string[];
17
+ scanActions(store: any): string[];
18
+ scan(store: any): StoreShape;
19
+ }
@@ -0,0 +1,109 @@
1
+ import { deepClone } from './utils';
2
+ import { DUCK_TAG } from '../async/marker';
3
+ import { COLLECTION_TAG, MULTI_COLLECTION_TAG, } from '../entities/collection/marker';
4
+ import { RECORD_TAG } from '../entities/record/marker';
5
+ const INTERNAL_KEYS = new Set([
6
+ 'deps',
7
+ 'root',
8
+ 'resetStore',
9
+ '__getSnapshot',
10
+ '__applySnapshot',
11
+ ]);
12
+ export class Scanner {
13
+ isDuck(value) {
14
+ return value && typeof value === 'object' && value[DUCK_TAG] === true;
15
+ }
16
+ isSingleCollection(value) {
17
+ return (value?.[COLLECTION_TAG] === true && value?.[MULTI_COLLECTION_TAG] !== true);
18
+ }
19
+ isMultiCollection(value) {
20
+ return value?.[MULTI_COLLECTION_TAG] === true;
21
+ }
22
+ isRecord(value) {
23
+ return value?.[RECORD_TAG] === true;
24
+ }
25
+ scanPlain(store) {
26
+ const out = {};
27
+ for (const key of Object.keys(store)) {
28
+ if (INTERNAL_KEYS.has(key)) {
29
+ continue;
30
+ }
31
+ const v = store[key];
32
+ if (typeof v === 'function') {
33
+ continue;
34
+ }
35
+ if (this.isDuck(v)) {
36
+ continue;
37
+ }
38
+ if (this.isSingleCollection(v)) {
39
+ continue;
40
+ }
41
+ if (this.isMultiCollection(v)) {
42
+ continue;
43
+ }
44
+ if (this.isRecord(v)) {
45
+ continue;
46
+ }
47
+ // IMPORTANT: store initial plain by VALUE (not by reference)
48
+ out[key] = deepClone(v);
49
+ }
50
+ return out;
51
+ }
52
+ scanSingleKeys(store) {
53
+ return Object.keys(store).filter(k => this.isSingleCollection(store[k]));
54
+ }
55
+ scanMultiKeys(store) {
56
+ return Object.keys(store).filter(k => this.isMultiCollection(store[k]));
57
+ }
58
+ scanRecordKeys(store) {
59
+ return Object.keys(store).filter(k => this.isRecord(store[k]));
60
+ }
61
+ scanActions(store) {
62
+ const out = new Set();
63
+ // instance methods (arrow fns on instance)
64
+ for (const key of Object.keys(store)) {
65
+ if (INTERNAL_KEYS.has(key)) {
66
+ continue;
67
+ }
68
+ const v = store[key];
69
+ if (this.isDuck(v)) {
70
+ continue;
71
+ }
72
+ if (typeof v === 'function' && !key.startsWith('_')) {
73
+ out.add(key);
74
+ }
75
+ }
76
+ // prototype methods
77
+ const proto = Object.getPrototypeOf(store);
78
+ for (const key of Object.getOwnPropertyNames(proto)) {
79
+ if (key === 'constructor') {
80
+ continue;
81
+ }
82
+ if (INTERNAL_KEYS.has(key)) {
83
+ continue;
84
+ }
85
+ if (key.startsWith('_')) {
86
+ continue;
87
+ }
88
+ const desc = Object.getOwnPropertyDescriptor(proto, key);
89
+ if (!desc) {
90
+ continue;
91
+ }
92
+ // only real methods, not getters/setters
93
+ if (typeof desc.value === 'function') {
94
+ out.add(key);
95
+ }
96
+ }
97
+ return [...out];
98
+ }
99
+ scan(store) {
100
+ return {
101
+ plain: this.scanPlain(store),
102
+ single: this.scanSingleKeys(store),
103
+ multi: this.scanMultiKeys(store),
104
+ records: this.scanRecordKeys(store),
105
+ actions: this.scanActions(store),
106
+ };
107
+ }
108
+ }
109
+ //# sourceMappingURL=scanner.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scanner.js","sourceRoot":"","sources":["../../src/create/scanner.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ export declare function defineHiddenProp<T extends object, K extends string>(obj: T, key: K, value: any): void;
2
+ export declare function deepClone<T>(value: T): T;
3
+ export declare function isPlainObject(value: unknown): value is Record<string, any>;
@@ -0,0 +1,33 @@
1
+ export function defineHiddenProp(obj, key, value) {
2
+ Object.defineProperty(obj, key, {
3
+ value,
4
+ enumerable: false,
5
+ configurable: true,
6
+ writable: true,
7
+ });
8
+ }
9
+ export function deepClone(value) {
10
+ // structuredClone is ideal for snapshots (handles Maps/Sets/Date, etc.)
11
+ // Fallback: JSON clone for plain data.
12
+ try {
13
+ if (typeof structuredClone === 'function') {
14
+ return structuredClone(value);
15
+ }
16
+ }
17
+ catch { }
18
+ try {
19
+ return JSON.parse(JSON.stringify(value));
20
+ }
21
+ catch {
22
+ // Last resort: return as-is (better than crash).
23
+ return value;
24
+ }
25
+ }
26
+ export function isPlainObject(value) {
27
+ if (!value || typeof value !== 'object') {
28
+ return false;
29
+ }
30
+ const proto = Object.getPrototypeOf(value);
31
+ return proto === Object.prototype || proto === null;
32
+ }
33
+ //# sourceMappingURL=utils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.js","sourceRoot":"","sources":["../../src/create/utils.ts"],"names":[],"mappings":"AAAA,MAAM,UAAU,gBAAgB,CAC9B,GAAM,EACN,GAAM,EACN,KAAU;IAEV,MAAM,CAAC,cAAc,CAAC,GAAG,EAAE,GAAG,EAAE;QAC9B,KAAK;QACL,UAAU,EAAE,KAAK;QACjB,YAAY,EAAE,IAAI;QAClB,QAAQ,EAAE,IAAI;KACf,CAAC,CAAC;AACL,CAAC;AAED,MAAM,UAAU,SAAS,CAAI,KAAQ;IACnC,wEAAwE;IACxE,uCAAuC;IACvC,IAAI,CAAC;QACH,IAAI,OAAO,eAAe,KAAK,UAAU,EAAE,CAAC;YAC1C,OAAO,eAAe,CAAC,KAAK,CAAC,CAAC;QAChC,CAAC;IACH,CAAC;IAAC,MAAM,CAAC,CAAA,CAAC;IAEV,IAAI,CAAC;QACH,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAM,CAAC;IAChD,CAAC;IAAC,MAAM,CAAC;QACP,iDAAiD;QACjD,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,KAAc;IAC1C,IAAI,CAAC,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QACxC,OAAO,KAAK,CAAC;IACf,CAAC;IACD,MAAM,KAAK,GAAG,MAAM,CAAC,cAAc,CAAC,KAAK,CAAC,CAAC;IAC3C,OAAO,KAAK,KAAK,MAAM,CAAC,SAAS,IAAI,KAAK,KAAK,IAAI,CAAC;AACtD,CAAC"}
@@ -0,0 +1,19 @@
1
+ import type { RootStore } from './root/RootStore';
2
+ /**
3
+ * Factory that returns typed hooks bound to a particular RootStore type.
4
+ *
5
+ * Usage in app:
6
+ * const { useStores, useServices, useCore, useStore, useService } =
7
+ * createHooks<typeof rootStore>();
8
+ */
9
+ export declare function createStoreHooks<TRoot extends RootStore<any, any, any, any>>(): {
10
+ useStores: () => TRoot["stores"];
11
+ useServices: () => TRoot["services"];
12
+ useStore: <K extends keyof TRoot["stores"]>(key: K) => {
13
+ [x: string]: any;
14
+ }[K];
15
+ useService: <K extends keyof TRoot["services"]>(key: K) => {
16
+ [x: string]: any;
17
+ }[K];
18
+ useCore: () => TRoot["core"];
19
+ };
@@ -0,0 +1,23 @@
1
+ import { getRootStore } from './di/register-root-store';
2
+ /**
3
+ * Factory that returns typed hooks bound to a particular RootStore type.
4
+ *
5
+ * Usage in app:
6
+ * const { useStores, useServices, useCore, useStore, useService } =
7
+ * createHooks<typeof rootStore>();
8
+ */
9
+ export function createStoreHooks() {
10
+ const useStores = () => getRootStore().stores;
11
+ const useServices = () => getRootStore().services;
12
+ const useStore = (key) => getRootStore().stores[key];
13
+ const useService = (key) => getRootStore().services[key];
14
+ const useCore = () => getRootStore().core;
15
+ return {
16
+ useStores,
17
+ useServices,
18
+ useStore,
19
+ useService,
20
+ useCore,
21
+ };
22
+ }
23
+ //# sourceMappingURL=create-store-hooks.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"create-store-hooks.js","sourceRoot":"","sources":["../src/create-store-hooks.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AAIxD;;;;;;GAMG;AACH,MAAM,UAAU,gBAAgB;IAG9B,MAAM,SAAS,GAAG,GAAoB,EAAE,CAAC,YAAY,EAAS,CAAC,MAAM,CAAC;IAEtE,MAAM,WAAW,GAAG,GAAsB,EAAE,CAAC,YAAY,EAAS,CAAC,QAAQ,CAAC;IAE5E,MAAM,QAAQ,GAAG,CAAkC,GAAM,EAAE,EAAE,CAC3D,YAAY,EAAS,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;IAEpC,MAAM,UAAU,GAAG,CAAoC,GAAM,EAAE,EAAE,CAC/D,YAAY,EAAS,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC;IAEtC,MAAM,OAAO,GAAG,GAAkB,EAAE,CAAC,YAAY,EAAS,CAAC,IAAI,CAAC;IAEhE,OAAO;QACL,SAAS;QACT,WAAW;QACX,QAAQ;QACR,UAAU;QACV,OAAO;KACR,CAAC;AACJ,CAAC"}
@@ -0,0 +1,2 @@
1
+ import { registerRootStore } from './register-root-store';
2
+ export { registerRootStore };
@@ -0,0 +1,3 @@
1
+ import { registerRootStore } from './register-root-store';
2
+ export { registerRootStore };
3
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/di/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAE1D,OAAO,EAAE,iBAAiB,EAAE,CAAC"}
@@ -0,0 +1,11 @@
1
+ import type { RootStore } from '../root/RootStore';
2
+ /**
3
+ * Registers the RootStore instance for global DI access.
4
+ * Should be called exactly once from the application entry point.
5
+ */
6
+ export declare function registerRootStore<TStore extends RootStore<any, any, any, any>>(store: TStore): void;
7
+ /**
8
+ * Returns the initialized RootStore instance.
9
+ * Throws if registerRootStore() has not been called yet.
10
+ */
11
+ export declare function getRootStore<TStore extends RootStore<any, any, any, any> = RootStore<any, any, any, any>>(): TStore;
@@ -0,0 +1,23 @@
1
+ /**
2
+ * Internal storage for the global RootStore reference.
3
+ * At runtime this will hold the actual app RootStore instance.
4
+ */
5
+ let _rootStore = null;
6
+ /**
7
+ * Registers the RootStore instance for global DI access.
8
+ * Should be called exactly once from the application entry point.
9
+ */
10
+ export function registerRootStore(store) {
11
+ _rootStore = store;
12
+ }
13
+ /**
14
+ * Returns the initialized RootStore instance.
15
+ * Throws if registerRootStore() has not been called yet.
16
+ */
17
+ export function getRootStore() {
18
+ if (!_rootStore) {
19
+ throw new Error('[core/di] RootStore is not initialized. Call registerRootStore(rootStore) first.');
20
+ }
21
+ return _rootStore;
22
+ }
23
+ //# sourceMappingURL=register-root-store.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"register-root-store.js","sourceRoot":"","sources":["../../src/di/register-root-store.ts"],"names":[],"mappings":"AAEA;;;GAGG;AACH,IAAI,UAAU,GAAyC,IAAI,CAAC;AAE5D;;;GAGG;AACH,MAAM,UAAU,iBAAiB,CAC/B,KAAa;IAEb,UAAU,GAAG,KAAK,CAAC;AACrB,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,YAAY;IAG1B,IAAI,CAAC,UAAU,EAAE,CAAC;QAChB,MAAM,IAAI,KAAK,CACb,kFAAkF,CACnF,CAAC;IACJ,CAAC;IAED,OAAO,UAAoB,CAAC;AAC9B,CAAC"}
@@ -0,0 +1,8 @@
1
+ import type { TEntitiesStore } from '../types';
2
+ import type { SchemaWalker } from './walker';
3
+ export declare class BucketCollector {
4
+ private entities;
5
+ private walker;
6
+ constructor(entities: TEntitiesStore, walker: SchemaWalker);
7
+ collect(entityKey: string, id: string | number): Record<string, Set<string>>;
8
+ }
@@ -0,0 +1,31 @@
1
+ export class BucketCollector {
2
+ constructor(entities, walker) {
3
+ this.entities = entities;
4
+ this.walker = walker;
5
+ }
6
+ collect(entityKey, id) {
7
+ const visited = new Set();
8
+ const bucket = {};
9
+ const walk = (key, entityId) => {
10
+ const visitKey = `${key}:${entityId}`;
11
+ if (visited.has(visitKey)) {
12
+ return;
13
+ }
14
+ visited.add(visitKey);
15
+ const entity = this.entities.getEntity(key, entityId);
16
+ if (!entity) {
17
+ return;
18
+ }
19
+ if (!bucket[key]) {
20
+ bucket[key] = new Set();
21
+ }
22
+ bucket[key].add(String(entityId));
23
+ this.walker.walkFields(key, entity, (childKey, childId) => {
24
+ walk(childKey, childId);
25
+ });
26
+ };
27
+ walk(entityKey, id);
28
+ return bucket;
29
+ }
30
+ }
31
+ //# sourceMappingURL=bucket.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bucket.js","sourceRoot":"","sources":["../../../src/entities/cleaner/bucket.ts"],"names":[],"mappings":"AAGA,MAAM,OAAO,eAAe;IAC1B,YACU,QAAwB,EACxB,MAAoB;QADpB,aAAQ,GAAR,QAAQ,CAAgB;QACxB,WAAM,GAAN,MAAM,CAAc;IAC3B,CAAC;IAEJ,OAAO,CAAC,SAAiB,EAAE,EAAmB;QAC5C,MAAM,OAAO,GAAG,IAAI,GAAG,EAAU,CAAC;QAClC,MAAM,MAAM,GAAgC,EAAS,CAAC;QAEtD,MAAM,IAAI,GAAG,CAAC,GAAW,EAAE,QAAyB,EAAE,EAAE;YACtD,MAAM,QAAQ,GAAG,GAAG,GAAG,IAAI,QAAQ,EAAE,CAAC;YACtC,IAAI,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC;gBAC1B,OAAO;YACT,CAAC;YACD,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;YAEtB,MAAM,MAAM,GAAG,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC;YAEtD,IAAI,CAAC,MAAM,EAAE,CAAC;gBACZ,OAAO;YACT,CAAC;YAED,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC;gBACjB,MAAM,CAAC,GAAG,CAAC,GAAG,IAAI,GAAG,EAAE,CAAC;YAC1B,CAAC;YACD,MAAM,CAAC,GAAG,CAAE,CAAC,GAAG,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC;YAEnC,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,GAAG,EAAE,MAAM,EAAE,CAAC,QAAQ,EAAE,OAAO,EAAE,EAAE;gBACxD,IAAI,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;YAC1B,CAAC,CAAC,CAAC;QACL,CAAC,CAAC;QAEF,IAAI,CAAC,SAAS,EAAE,EAAE,CAAC,CAAC;QAEpB,OAAO,MAAM,CAAC;IAChB,CAAC;CACF"}
@@ -0,0 +1 @@
1
+ export * from './store';
@@ -0,0 +1,2 @@
1
+ export * from './store';
2
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/entities/cleaner/index.ts"],"names":[],"mappings":"AAAA,cAAc,SAAS,CAAC"}
@@ -0,0 +1,12 @@
1
+ import type { AnySchema, TEntitiesStore } from '../types';
2
+ export declare class EntityCleanerStore {
3
+ private entities;
4
+ private walker;
5
+ private collector;
6
+ constructor(entities: TEntitiesStore, schemaMap: Record<string, AnySchema>);
7
+ private canDelete;
8
+ private collectCascade;
9
+ private filterBucket;
10
+ private detachRefByPlan;
11
+ deleteCascade(entityKey: string, ids: (string | number)[], sourceRefId: string): void;
12
+ }
@@ -0,0 +1,73 @@
1
+ import { BucketCollector } from './bucket';
2
+ import { SchemaWalker } from './walker';
3
+ import { META } from '../../constants/values';
4
+ export class EntityCleanerStore {
5
+ constructor(entities, schemaMap) {
6
+ this.entities = entities;
7
+ this.walker = new SchemaWalker(schemaMap);
8
+ this.collector = new BucketCollector(entities, this.walker);
9
+ }
10
+ canDelete(entityKey, id) {
11
+ const live = this.entities.getEntity(entityKey, id);
12
+ if (!live) {
13
+ return false;
14
+ }
15
+ if (live.__partial) {
16
+ return false;
17
+ }
18
+ const refs = live[META]?.refSources;
19
+ return !refs || refs.size === 0;
20
+ }
21
+ collectCascade(entityKey, ids) {
22
+ const finalBucket = {};
23
+ for (const id of ids) {
24
+ const bucket = this.collector.collect(entityKey, id);
25
+ for (const key of Object.keys(bucket)) {
26
+ if (!finalBucket[key]) {
27
+ finalBucket[key] = new Set();
28
+ }
29
+ bucket[key].forEach(v => finalBucket[key].add(v));
30
+ }
31
+ }
32
+ return finalBucket;
33
+ }
34
+ filterBucket(bucket) {
35
+ const filtered = {};
36
+ for (const key of Object.keys(bucket)) {
37
+ for (const id of bucket[key]) {
38
+ if (this.canDelete(key, id)) {
39
+ if (!filtered[key]) {
40
+ filtered[key] = new Set();
41
+ }
42
+ filtered[key].add(id);
43
+ }
44
+ }
45
+ }
46
+ return filtered;
47
+ }
48
+ detachRefByPlan(bucket, sourceRefId) {
49
+ for (const entityKey of Object.keys(bucket)) {
50
+ for (const id of bucket[entityKey]) {
51
+ const entity = this.entities.getEntity(entityKey, id);
52
+ if (!entity) {
53
+ continue;
54
+ }
55
+ const refs = entity[META]?.refSources;
56
+ if (!refs) {
57
+ continue;
58
+ }
59
+ refs.delete(sourceRefId);
60
+ }
61
+ }
62
+ }
63
+ deleteCascade(entityKey, ids, sourceRefId) {
64
+ if (!ids.length) {
65
+ return;
66
+ }
67
+ const raw = this.collectCascade(entityKey, ids);
68
+ this.detachRefByPlan(raw, sourceRefId);
69
+ const toDetach = this.filterBucket(raw);
70
+ this.entities.removeMany(toDetach);
71
+ }
72
+ }
73
+ //# sourceMappingURL=store.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"store.js","sourceRoot":"","sources":["../../../src/entities/cleaner/store.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ import type { AnySchema } from '../types';
2
+ export declare class SchemaWalker {
3
+ private schemaMap;
4
+ constructor(schemaMap: Record<string, AnySchema>);
5
+ walkFields(entityKey: string, entity: any, cb: (childKey: string, id: string | number) => void): void;
6
+ }
@@ -0,0 +1,34 @@
1
+ export class SchemaWalker {
2
+ constructor(schemaMap) {
3
+ this.schemaMap = schemaMap;
4
+ }
5
+ walkFields(entityKey, entity, cb) {
6
+ const schema = this.schemaMap[entityKey];
7
+ if (!schema) {
8
+ return;
9
+ }
10
+ for (const field of Object.keys(schema.definition)) {
11
+ const subschema = schema.definition[field];
12
+ const isArray = Array.isArray(subschema);
13
+ const childSchema = isArray ? subschema[0] : subschema;
14
+ const childKey = childSchema.key;
15
+ const idKey = `${field}Id`;
16
+ const value = entity[idKey];
17
+ if (!value) {
18
+ continue;
19
+ }
20
+ if (isArray) {
21
+ if (!Array.isArray(value)) {
22
+ continue;
23
+ }
24
+ for (const id of value) {
25
+ cb(childKey, id);
26
+ }
27
+ }
28
+ else {
29
+ cb(childKey, value);
30
+ }
31
+ }
32
+ }
33
+ }
34
+ //# sourceMappingURL=walker.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"walker.js","sourceRoot":"","sources":["../../../src/entities/cleaner/walker.ts"],"names":[],"mappings":"AAEA,MAAM,OAAO,YAAY;IACvB,YAAoB,SAAoC;QAApC,cAAS,GAAT,SAAS,CAA2B;IAAG,CAAC;IAE5D,UAAU,CACR,SAAiB,EACjB,MAAW,EACX,EAAmD;QAEnD,MAAM,MAAM,GAAG,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC;QACzC,IAAI,CAAC,MAAM,EAAE,CAAC;YACZ,OAAO;QACT,CAAC;QAED,KAAK,MAAM,KAAK,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,EAAE,CAAC;YACnD,MAAM,SAAS,GAAG,MAAM,CAAC,UAAU,CAAC,KAAK,CAA4B,CAAC;YACtE,MAAM,OAAO,GAAG,KAAK,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;YACzC,MAAM,WAAW,GAAG,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;YAEvD,MAAM,QAAQ,GAAG,WAAW,CAAC,GAAG,CAAC;YAEjC,MAAM,KAAK,GAAG,GAAG,KAAK,IAAI,CAAC;YAC3B,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC;YAC5B,IAAI,CAAC,KAAK,EAAE,CAAC;gBACX,SAAS;YACX,CAAC;YAED,IAAI,OAAO,EAAE,CAAC;gBACZ,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;oBAC1B,SAAS;gBACX,CAAC;gBACD,KAAK,MAAM,EAAE,IAAI,KAAK,EAAE,CAAC;oBACvB,EAAE,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC;gBACnB,CAAC;YACH,CAAC;iBAAM,CAAC;gBACN,EAAE,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAC;YACtB,CAAC;QACH,CAAC;IACH,CAAC;CACF"}
@@ -0,0 +1,9 @@
1
+ import { EntityCollection } from './entity-collection';
2
+ import type { MultiEntityCollection } from './public';
3
+ import type { EntityCollectionOptions, SystemDeps } from './types';
4
+ export declare function createEntityCollection<T extends {
5
+ id: string | number;
6
+ }, M>(options: EntityCollectionOptions<T>, system: SystemDeps): EntityCollection<T, M>;
7
+ export declare function createMultiEntityCollection<T extends {
8
+ id: string | number;
9
+ }, M>(options: EntityCollectionOptions<T>, system: SystemDeps): MultiEntityCollection<T, M>;
@@ -0,0 +1,17 @@
1
+ import { EntityCollection } from './entity-collection';
2
+ import { MultiEntityCollection as ProxyEntityCollection } from './multi-entity-collection';
3
+ export function createEntityCollection(options, system) {
4
+ if (__DEV__) {
5
+ if (!options.entityKey) {
6
+ console.warn('[EntityRecord] Missing "entityKey" in options');
7
+ }
8
+ if (!options.collectionId) {
9
+ console.warn('[EntityRecord] Missing "collectionId" in options');
10
+ }
11
+ }
12
+ return new EntityCollection(options, system);
13
+ }
14
+ export function createMultiEntityCollection(options, system) {
15
+ return new ProxyEntityCollection(options, system).getProxy();
16
+ }
17
+ //# sourceMappingURL=create-entity-collection.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"create-entity-collection.js","sourceRoot":"","sources":["../../../src/entities/collection/create-entity-collection.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AACvD,OAAO,EAAE,qBAAqB,IAAI,qBAAqB,EAAE,MAAM,2BAA2B,CAAC;AAK3F,MAAM,UAAU,sBAAsB,CACpC,OAAmC,EACnC,MAAkB;IAElB,IAAI,OAAO,EAAE,CAAC;QACZ,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,CAAC;YACvB,OAAO,CAAC,IAAI,CAAC,+CAA+C,CAAC,CAAC;QAChE,CAAC;QAED,IAAI,CAAC,OAAO,CAAC,YAAY,EAAE,CAAC;YAC1B,OAAO,CAAC,IAAI,CAAC,kDAAkD,CAAC,CAAC;QACnE,CAAC;IACH,CAAC;IAED,OAAO,IAAI,gBAAgB,CAAO,OAAO,EAAE,MAAM,CAAC,CAAC;AACrD,CAAC;AAED,MAAM,UAAU,2BAA2B,CAIzC,OAAmC,EACnC,MAAkB;IAElB,OAAO,IAAI,qBAAqB,CAAO,OAAO,EAAE,MAAM,CAAC,CAAC,QAAQ,EAAE,CAAC;AACrE,CAAC"}