@warp-drive/core 5.6.0-alpha.14 → 5.6.0-alpha.17

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 (287) hide show
  1. package/declarations/build-config/babel-macros.d.ts +1 -2
  2. package/declarations/build-config/canary-features.d.ts +1 -2
  3. package/declarations/build-config/debugging.d.ts +1 -2
  4. package/declarations/build-config/deprecations.d.ts +1 -2
  5. package/declarations/build-config/env.d.ts +1 -2
  6. package/declarations/build-config/macros.d.ts +1 -2
  7. package/declarations/build-config.d.ts +1 -2
  8. package/declarations/configure.d.ts +6 -7
  9. package/declarations/graph/-private/-diff.d.ts +21 -22
  10. package/declarations/graph/-private/-edge-definition.d.ts +134 -135
  11. package/declarations/graph/-private/-state.d.ts +93 -7
  12. package/declarations/graph/-private/-utils.d.ts +18 -13
  13. package/declarations/graph/-private/coerce-id.d.ts +6 -1
  14. package/declarations/graph/-private/debug/assert-polymorphic-type.d.ts +15 -4
  15. package/declarations/graph/-private/edges/collection.d.ts +35 -36
  16. package/declarations/graph/-private/edges/implicit.d.ts +28 -29
  17. package/declarations/graph/-private/edges/resource.d.ts +19 -20
  18. package/declarations/graph/-private/graph.d.ts +83 -48
  19. package/declarations/graph/-private/normalize-link.d.ts +7 -2
  20. package/declarations/graph/-private/operations/add-to-related-records.d.ts +3 -4
  21. package/declarations/graph/-private/operations/merge-identifier.d.ts +2 -3
  22. package/declarations/graph/-private/operations/remove-from-related-records.d.ts +3 -4
  23. package/declarations/graph/-private/operations/replace-related-record.d.ts +2 -3
  24. package/declarations/graph/-private/operations/replace-related-records.d.ts +58 -4
  25. package/declarations/graph/-private/operations/update-relationship.d.ts +11 -9
  26. package/declarations/graph/-private.d.ts +9 -10
  27. package/declarations/index.d.ts +11 -12
  28. package/declarations/reactive/-private/document.d.ts +143 -144
  29. package/declarations/reactive/-private/fields/compute.d.ts +31 -28
  30. package/declarations/reactive/-private/fields/extension.d.ts +8 -0
  31. package/declarations/reactive/-private/fields/managed-array.d.ts +19 -20
  32. package/declarations/reactive/-private/fields/managed-object.d.ts +16 -16
  33. package/declarations/reactive/-private/fields/many-array-manager.d.ts +15 -16
  34. package/declarations/reactive/-private/hooks.d.ts +3 -4
  35. package/declarations/reactive/-private/record.d.ts +61 -58
  36. package/declarations/reactive/-private/schema.d.ts +256 -165
  37. package/declarations/reactive/-private/symbols.d.ts +27 -2
  38. package/declarations/reactive/-private.d.ts +1 -2
  39. package/declarations/reactive.d.ts +4 -5
  40. package/declarations/request/-private/context.d.ts +34 -35
  41. package/declarations/request/-private/debug.d.ts +2 -3
  42. package/declarations/request/-private/fetch.d.ts +23 -24
  43. package/declarations/request/-private/future.d.ts +3 -4
  44. package/declarations/request/-private/manager.d.ts +159 -157
  45. package/declarations/request/-private/promise-cache.d.ts +21 -13
  46. package/declarations/request/-private/types.d.ts +124 -124
  47. package/declarations/request/-private/utils.d.ts +8 -9
  48. package/declarations/request.d.ts +5 -6
  49. package/declarations/store/-private/cache-handler/handler.d.ts +57 -52
  50. package/declarations/store/-private/cache-handler/types.d.ts +95 -96
  51. package/declarations/store/-private/cache-handler/utils.d.ts +16 -16
  52. package/declarations/store/-private/caches/cache-utils.d.ts +7 -4
  53. package/declarations/store/-private/caches/identifier-cache.d.ts +234 -246
  54. package/declarations/store/-private/caches/instance-cache.d.ts +47 -47
  55. package/declarations/store/-private/caches/resource-utils.d.ts +3 -4
  56. package/declarations/store/-private/debug/utils.d.ts +6 -7
  57. package/declarations/store/-private/default-cache-policy.d.ts +362 -361
  58. package/declarations/store/-private/legacy-model-support/record-reference.d.ts +154 -159
  59. package/declarations/store/-private/legacy-model-support/shim-model-class.d.ts +14 -14
  60. package/declarations/store/-private/managers/cache-capabilities-manager.d.ts +21 -22
  61. package/declarations/store/-private/managers/cache-manager.d.ts +440 -425
  62. package/declarations/store/-private/managers/notification-manager.d.ts +88 -83
  63. package/declarations/store/-private/managers/record-array-manager.d.ts +89 -90
  64. package/declarations/store/-private/network/request-cache.d.ts +86 -83
  65. package/declarations/store/-private/new-core-tmp/promise-state.d.ts +252 -244
  66. package/declarations/store/-private/new-core-tmp/reactivity/configure.d.ts +155 -72
  67. package/declarations/store/-private/new-core-tmp/reactivity/internal.d.ts +148 -149
  68. package/declarations/store/-private/new-core-tmp/reactivity/signal.d.ts +28 -23
  69. package/declarations/store/-private/new-core-tmp/request-state.d.ts +263 -241
  70. package/declarations/store/-private/new-core-tmp/request-subscription.d.ts +261 -0
  71. package/declarations/store/-private/record-arrays/identifier-array.d.ts +125 -119
  72. package/declarations/store/-private/record-arrays/many-array.d.ts +180 -182
  73. package/declarations/store/-private/record-arrays/native-proxy-type-fix.d.ts +120 -110
  74. package/declarations/store/-private/store-service.d.ts +1594 -1586
  75. package/declarations/store/-private/utils/coerce-id.d.ts +6 -1
  76. package/declarations/store/-private/utils/construct-resource.d.ts +1 -2
  77. package/declarations/store/-private/utils/is-non-empty-string.d.ts +0 -1
  78. package/declarations/store/-private/utils/normalize-model-name.d.ts +0 -1
  79. package/declarations/store/-private/utils/uuid-polyfill.d.ts +0 -1
  80. package/declarations/store/-private.d.ts +31 -27
  81. package/declarations/store/-types/q/cache-capabilities-manager.d.ts +96 -97
  82. package/declarations/store/-types/q/ds-model.d.ts +17 -18
  83. package/declarations/store/-types/q/identifier.d.ts +11 -12
  84. package/declarations/store/-types/q/record-instance.d.ts +16 -17
  85. package/declarations/store/-types/q/schema-service.d.ts +346 -323
  86. package/declarations/store/-types/q/store.d.ts +25 -28
  87. package/declarations/store.d.ts +1 -2
  88. package/declarations/types/-private.d.ts +16 -8
  89. package/declarations/types/cache/aliases.d.ts +11 -1
  90. package/declarations/types/cache/change.d.ts +4 -5
  91. package/declarations/types/cache/mutations.d.ts +51 -28
  92. package/declarations/types/cache/operations.d.ts +60 -47
  93. package/declarations/types/cache/relationship.d.ts +11 -9
  94. package/declarations/types/cache.d.ts +495 -484
  95. package/declarations/types/graph.d.ts +31 -32
  96. package/declarations/types/identifier.d.ts +83 -82
  97. package/declarations/types/json/raw.d.ts +1 -2
  98. package/declarations/types/params.d.ts +4 -5
  99. package/declarations/types/record.d.ts +117 -76
  100. package/declarations/types/request.d.ts +289 -266
  101. package/declarations/types/runtime.d.ts +8 -9
  102. package/declarations/types/schema/concepts.d.ts +19 -13
  103. package/declarations/types/schema/fields.d.ts +1712 -1587
  104. package/declarations/types/schema/fields.type-test.d.ts +0 -1
  105. package/declarations/types/spec/document.d.ts +28 -22
  106. package/declarations/types/spec/error.d.ts +16 -17
  107. package/declarations/types/spec/json-api-raw.d.ts +102 -102
  108. package/declarations/types/symbols.d.ts +74 -75
  109. package/declarations/types/utils.d.ts +5 -5
  110. package/declarations/types.d.ts +10 -11
  111. package/declarations/utils/string.d.ts +43 -40
  112. package/dist/{configure-BgaZESRo.js → configure-B48bFHOl.js} +38 -2
  113. package/dist/configure.js +1 -1
  114. package/dist/graph/-private.js +2 -2
  115. package/dist/{handler-cHghx9Y9.js → handler-C2T-IyJK.js} +1 -1
  116. package/dist/index.js +3 -3
  117. package/dist/reactive/-private.js +1 -1
  118. package/dist/reactive.js +287 -101
  119. package/dist/{request-state-DgwTEXLU.js → request-state-CjLph1LP.js} +1030 -249
  120. package/dist/store/-private.js +3 -3
  121. package/dist/{symbols-BmDcn6hS.js → symbols-SIstXMLI.js} +3 -3
  122. package/dist/types/-private.js +1 -1
  123. package/dist/types/schema/fields.js +4 -4
  124. package/package.json +4 -4
  125. package/declarations/build-config/babel-macros.d.ts.map +0 -1
  126. package/declarations/build-config/canary-features.d.ts.map +0 -1
  127. package/declarations/build-config/debugging.d.ts.map +0 -1
  128. package/declarations/build-config/deprecations.d.ts.map +0 -1
  129. package/declarations/build-config/env.d.ts.map +0 -1
  130. package/declarations/build-config/macros.d.ts.map +0 -1
  131. package/declarations/build-config.d.ts.map +0 -1
  132. package/declarations/configure.d.ts.map +0 -1
  133. package/declarations/graph/-private/-diff.d.ts.map +0 -1
  134. package/declarations/graph/-private/-edge-definition.d.ts.map +0 -1
  135. package/declarations/graph/-private/-state.d.ts.map +0 -1
  136. package/declarations/graph/-private/-utils.d.ts.map +0 -1
  137. package/declarations/graph/-private/coerce-id.d.ts.map +0 -1
  138. package/declarations/graph/-private/debug/assert-polymorphic-type.d.ts.map +0 -1
  139. package/declarations/graph/-private/edges/collection.d.ts.map +0 -1
  140. package/declarations/graph/-private/edges/implicit.d.ts.map +0 -1
  141. package/declarations/graph/-private/edges/resource.d.ts.map +0 -1
  142. package/declarations/graph/-private/graph.d.ts.map +0 -1
  143. package/declarations/graph/-private/normalize-link.d.ts.map +0 -1
  144. package/declarations/graph/-private/operations/add-to-related-records.d.ts.map +0 -1
  145. package/declarations/graph/-private/operations/merge-identifier.d.ts.map +0 -1
  146. package/declarations/graph/-private/operations/remove-from-related-records.d.ts.map +0 -1
  147. package/declarations/graph/-private/operations/replace-related-record.d.ts.map +0 -1
  148. package/declarations/graph/-private/operations/replace-related-records.d.ts.map +0 -1
  149. package/declarations/graph/-private/operations/update-relationship.d.ts.map +0 -1
  150. package/declarations/graph/-private.d.ts.map +0 -1
  151. package/declarations/index.d.ts.map +0 -1
  152. package/declarations/reactive/-private/document.d.ts.map +0 -1
  153. package/declarations/reactive/-private/fields/compute.d.ts.map +0 -1
  154. package/declarations/reactive/-private/fields/managed-array.d.ts.map +0 -1
  155. package/declarations/reactive/-private/fields/managed-object.d.ts.map +0 -1
  156. package/declarations/reactive/-private/fields/many-array-manager.d.ts.map +0 -1
  157. package/declarations/reactive/-private/hooks.d.ts.map +0 -1
  158. package/declarations/reactive/-private/record.d.ts.map +0 -1
  159. package/declarations/reactive/-private/schema.d.ts.map +0 -1
  160. package/declarations/reactive/-private/symbols.d.ts.map +0 -1
  161. package/declarations/reactive/-private.d.ts.map +0 -1
  162. package/declarations/reactive.d.ts.map +0 -1
  163. package/declarations/request/-private/context.d.ts.map +0 -1
  164. package/declarations/request/-private/debug.d.ts.map +0 -1
  165. package/declarations/request/-private/fetch.d.ts.map +0 -1
  166. package/declarations/request/-private/future.d.ts.map +0 -1
  167. package/declarations/request/-private/manager.d.ts.map +0 -1
  168. package/declarations/request/-private/promise-cache.d.ts.map +0 -1
  169. package/declarations/request/-private/types.d.ts.map +0 -1
  170. package/declarations/request/-private/utils.d.ts.map +0 -1
  171. package/declarations/request.d.ts.map +0 -1
  172. package/declarations/store/-private/cache-handler/handler.d.ts.map +0 -1
  173. package/declarations/store/-private/cache-handler/types.d.ts.map +0 -1
  174. package/declarations/store/-private/cache-handler/utils.d.ts.map +0 -1
  175. package/declarations/store/-private/caches/cache-utils.d.ts.map +0 -1
  176. package/declarations/store/-private/caches/identifier-cache.d.ts.map +0 -1
  177. package/declarations/store/-private/caches/instance-cache.d.ts.map +0 -1
  178. package/declarations/store/-private/caches/resource-utils.d.ts.map +0 -1
  179. package/declarations/store/-private/debug/utils.d.ts.map +0 -1
  180. package/declarations/store/-private/default-cache-policy.d.ts.map +0 -1
  181. package/declarations/store/-private/legacy-model-support/record-reference.d.ts.map +0 -1
  182. package/declarations/store/-private/legacy-model-support/shim-model-class.d.ts.map +0 -1
  183. package/declarations/store/-private/managers/cache-capabilities-manager.d.ts.map +0 -1
  184. package/declarations/store/-private/managers/cache-manager.d.ts.map +0 -1
  185. package/declarations/store/-private/managers/notification-manager.d.ts.map +0 -1
  186. package/declarations/store/-private/managers/record-array-manager.d.ts.map +0 -1
  187. package/declarations/store/-private/network/request-cache.d.ts.map +0 -1
  188. package/declarations/store/-private/new-core-tmp/promise-state.d.ts.map +0 -1
  189. package/declarations/store/-private/new-core-tmp/reactivity/configure.d.ts.map +0 -1
  190. package/declarations/store/-private/new-core-tmp/reactivity/internal.d.ts.map +0 -1
  191. package/declarations/store/-private/new-core-tmp/reactivity/signal.d.ts.map +0 -1
  192. package/declarations/store/-private/new-core-tmp/request-state.d.ts.map +0 -1
  193. package/declarations/store/-private/record-arrays/identifier-array.d.ts.map +0 -1
  194. package/declarations/store/-private/record-arrays/many-array.d.ts.map +0 -1
  195. package/declarations/store/-private/record-arrays/native-proxy-type-fix.d.ts.map +0 -1
  196. package/declarations/store/-private/store-service.d.ts.map +0 -1
  197. package/declarations/store/-private/store-service.type-test.d.ts +0 -2
  198. package/declarations/store/-private/store-service.type-test.d.ts.map +0 -1
  199. package/declarations/store/-private/utils/coerce-id.d.ts.map +0 -1
  200. package/declarations/store/-private/utils/construct-resource.d.ts.map +0 -1
  201. package/declarations/store/-private/utils/is-non-empty-string.d.ts.map +0 -1
  202. package/declarations/store/-private/utils/normalize-model-name.d.ts.map +0 -1
  203. package/declarations/store/-private/utils/uuid-polyfill.d.ts.map +0 -1
  204. package/declarations/store/-private.d.ts.map +0 -1
  205. package/declarations/store/-types/q/cache-capabilities-manager.d.ts.map +0 -1
  206. package/declarations/store/-types/q/ds-model.d.ts.map +0 -1
  207. package/declarations/store/-types/q/identifier.d.ts.map +0 -1
  208. package/declarations/store/-types/q/promise-proxies.d.ts +0 -2
  209. package/declarations/store/-types/q/promise-proxies.d.ts.map +0 -1
  210. package/declarations/store/-types/q/record-data-json-api.d.ts +0 -31
  211. package/declarations/store/-types/q/record-data-json-api.d.ts.map +0 -1
  212. package/declarations/store/-types/q/record-instance.d.ts.map +0 -1
  213. package/declarations/store/-types/q/schema-service.d.ts.map +0 -1
  214. package/declarations/store/-types/q/store.d.ts.map +0 -1
  215. package/declarations/store.d.ts.map +0 -1
  216. package/declarations/types/-private.d.ts.map +0 -1
  217. package/declarations/types/cache/aliases.d.ts.map +0 -1
  218. package/declarations/types/cache/change.d.ts.map +0 -1
  219. package/declarations/types/cache/mutations.d.ts.map +0 -1
  220. package/declarations/types/cache/operations.d.ts.map +0 -1
  221. package/declarations/types/cache/relationship.d.ts.map +0 -1
  222. package/declarations/types/cache.d.ts.map +0 -1
  223. package/declarations/types/graph.d.ts.map +0 -1
  224. package/declarations/types/identifier.d.ts.map +0 -1
  225. package/declarations/types/json/raw.d.ts.map +0 -1
  226. package/declarations/types/params.d.ts.map +0 -1
  227. package/declarations/types/record.d.ts.map +0 -1
  228. package/declarations/types/record.type-test.d.ts +0 -2
  229. package/declarations/types/record.type-test.d.ts.map +0 -1
  230. package/declarations/types/request.d.ts.map +0 -1
  231. package/declarations/types/request.type-test.d.ts +0 -2
  232. package/declarations/types/request.type-test.d.ts.map +0 -1
  233. package/declarations/types/runtime.d.ts.map +0 -1
  234. package/declarations/types/schema/concepts.d.ts.map +0 -1
  235. package/declarations/types/schema/fields.d.ts.map +0 -1
  236. package/declarations/types/schema/fields.type-test.d.ts.map +0 -1
  237. package/declarations/types/spec/document.d.ts.map +0 -1
  238. package/declarations/types/spec/error.d.ts.map +0 -1
  239. package/declarations/types/spec/json-api-raw.d.ts.map +0 -1
  240. package/declarations/types/symbols.d.ts.map +0 -1
  241. package/declarations/types/utils.d.ts.map +0 -1
  242. package/declarations/types.d.ts.map +0 -1
  243. package/declarations/utils/string.d.ts.map +0 -1
  244. package/dist/build-config/babel-macros.js.map +0 -1
  245. package/dist/build-config/canary-features.js.map +0 -1
  246. package/dist/build-config/debugging.js.map +0 -1
  247. package/dist/build-config/deprecations.js.map +0 -1
  248. package/dist/build-config/env.js.map +0 -1
  249. package/dist/build-config/macros.js.map +0 -1
  250. package/dist/build-config.js.map +0 -1
  251. package/dist/configure-BgaZESRo.js.map +0 -1
  252. package/dist/configure.js.map +0 -1
  253. package/dist/context-COmAnXUQ.js.map +0 -1
  254. package/dist/graph/-private.js.map +0 -1
  255. package/dist/handler-cHghx9Y9.js.map +0 -1
  256. package/dist/index.js.map +0 -1
  257. package/dist/reactive/-private.js.map +0 -1
  258. package/dist/reactive.js.map +0 -1
  259. package/dist/request-state-DgwTEXLU.js.map +0 -1
  260. package/dist/request.js.map +0 -1
  261. package/dist/store/-private.js.map +0 -1
  262. package/dist/store.js.map +0 -1
  263. package/dist/symbols-BmDcn6hS.js.map +0 -1
  264. package/dist/types/-private.js.map +0 -1
  265. package/dist/types/cache/aliases.js.map +0 -1
  266. package/dist/types/cache/change.js.map +0 -1
  267. package/dist/types/cache/mutations.js.map +0 -1
  268. package/dist/types/cache/operations.js.map +0 -1
  269. package/dist/types/cache/relationship.js.map +0 -1
  270. package/dist/types/cache.js.map +0 -1
  271. package/dist/types/graph.js.map +0 -1
  272. package/dist/types/identifier.js.map +0 -1
  273. package/dist/types/json/raw.js.map +0 -1
  274. package/dist/types/params.js.map +0 -1
  275. package/dist/types/record.js.map +0 -1
  276. package/dist/types/request.js.map +0 -1
  277. package/dist/types/runtime.js.map +0 -1
  278. package/dist/types/schema/concepts.js.map +0 -1
  279. package/dist/types/schema/fields.js.map +0 -1
  280. package/dist/types/schema/fields.type-test.js.map +0 -1
  281. package/dist/types/spec/document.js.map +0 -1
  282. package/dist/types/spec/error.js.map +0 -1
  283. package/dist/types/spec/json-api-raw.js.map +0 -1
  284. package/dist/types/symbols.js.map +0 -1
  285. package/dist/types/utils.js.map +0 -1
  286. package/dist/types.js.map +0 -1
  287. package/dist/utils/string.js.map +0 -1
package/dist/reactive.js CHANGED
@@ -1,13 +1,13 @@
1
1
  import { isResourceSchema } from './types/schema/fields.js';
2
- import { B as withSignalStore, w as entangleSignal, E as consumeInternalSignal, d as SOURCE$1, f as fastPush, x as defineSignal, l as RelatedCollection, F as getOrCreateInternalSignal, D as notifyInternalSignal, z as Signals, h as setRecordIdentifier, r as recordIdentifierFor } from "./request-state-DgwTEXLU.js";
2
+ import { E as withSignalStore, Q as isExtensionProp, T as performExtensionSet, G as consumeInternalSignal, U as performArrayExtensionGet, x as entangleSignal, V as performObjectExtensionGet, d as SOURCE$1, f as fastPush, y as defineSignal, l as RelatedCollection, H as getOrCreateInternalSignal, F as notifyInternalSignal, A as Signals, h as setRecordIdentifier, r as recordIdentifierFor } from "./request-state-CjLph1LP.js";
3
3
  import { EnableHydration, STRUCTURED } from './types/request.js';
4
4
  import { macroCondition, getGlobalConfig } from '@embroider/macros';
5
5
  import { deprecate } from '@ember/debug';
6
6
  import './utils/string.js';
7
- import { A as ARRAY_SIGNAL, O as OBJECT_SIGNAL, c as createMemo } from "./configure-BgaZESRo.js";
7
+ import { A as ARRAY_SIGNAL, O as OBJECT_SIGNAL, c as createMemo } from "./configure-B48bFHOl.js";
8
8
  import { RecordStore, Type } from './types/symbols.js';
9
9
  import { getOrSetGlobal } from './types/-private.js';
10
- import { S as SOURCE, E as Editable, L as Legacy, I as Identifier, P as Parent, a as EmbeddedPath, D as Destroy, C as Checkout, b as EmbeddedType } from "./symbols-BmDcn6hS.js";
10
+ import { S as SOURCE, E as Editable, L as Legacy, I as Identifier, P as Parent, a as EmbeddedPath, D as Destroy, C as Checkout, b as EmbeddedField } from "./symbols-SIstXMLI.js";
11
11
  import './index.js';
12
12
  const ARRAY_GETTER_METHODS = new Set([Symbol.iterator, 'concat', 'entries', 'every', 'fill', 'filter', 'find', 'findIndex', 'flat', 'flatMap', 'forEach', 'includes', 'indexOf', 'join', 'keys', 'lastIndexOf', 'map', 'reduce', 'reduceRight', 'slice', 'some', 'values']);
13
13
  // const ARRAY_SETTER_METHODS = new Set<KeyType>(['push', 'pop', 'unshift', 'shift', 'splice', 'sort']);
@@ -53,19 +53,16 @@ function safeForEach(instance, arr, store, callback, target) {
53
53
  }
54
54
  return instance;
55
55
  }
56
+ // eslint-disable-next-line @typescript-eslint/no-extraneous-class
56
57
  class ManagedArray {
57
- [SOURCE];
58
58
  constructor(store, schema, cache, field, data, identifier, path, owner, isSchemaArray, editable, legacy) {
59
59
  // eslint-disable-next-line @typescript-eslint/no-this-alias
60
60
  const self = this;
61
61
  this[SOURCE] = data?.slice();
62
62
  const IS_EDITABLE = this[Editable] = editable ?? false;
63
63
  this[Legacy] = legacy;
64
-
65
- // FIXME probably can get rid of the manual ARRAY_SIGNAL storage
66
- // FIXME probably the storage should be on the proxy/receiver not this class
67
64
  const signals = withSignalStore(this);
68
- const _SIGNAL = this[ARRAY_SIGNAL] = entangleSignal(signals, this, ARRAY_SIGNAL, undefined);
65
+ let _SIGNAL = null;
69
66
  const boundFns = new Map();
70
67
  this.identifier = identifier;
71
68
  this.path = path;
@@ -81,6 +78,7 @@ class ManagedArray {
81
78
  // into two separate methods.
82
79
  Map;
83
80
  const ManagedRecordRefs = isSchemaArray ? new RefStorage() : null;
81
+ const extensions = legacy ? schema.CAUTION_MEGA_DANGER_ZONE_arrayExtensions(field) : null;
84
82
  const proxy = new Proxy(this[SOURCE], {
85
83
  get(target, prop, receiver) {
86
84
  if (prop === ARRAY_SIGNAL) {
@@ -101,6 +99,10 @@ class ManagedArray {
101
99
  self[SOURCE].push(...newData);
102
100
  }
103
101
  }
102
+ if (prop === 'length') {
103
+ return consumeInternalSignal(_SIGNAL), target.length;
104
+ }
105
+ if (prop === '[]') return consumeInternalSignal(_SIGNAL), receiver;
104
106
  if (index !== null) {
105
107
  let val;
106
108
  if (mode === '@hash') {
@@ -159,7 +161,7 @@ class ManagedArray {
159
161
  record = new ReactiveResource(store, recordIdentifier, {
160
162
  [Editable]: self.owner[Editable],
161
163
  [Legacy]: self.owner[Legacy]
162
- }, true, field.type, recordPath);
164
+ }, true, field, recordPath);
163
165
  // if mode is not @identity or @index, then access the key path now
164
166
  // to determine the key value.
165
167
  // chris says we can implement this as a special kind `@hash` which
@@ -224,6 +226,9 @@ class ManagedArray {
224
226
  }
225
227
  return fn;
226
228
  }
229
+ if (isExtensionProp(extensions, prop)) {
230
+ return performArrayExtensionGet(receiver, extensions, signals, prop, _SIGNAL, boundFns, v => void (transaction = v));
231
+ }
227
232
  return Reflect.get(target, prop, receiver);
228
233
  },
229
234
  set(target, prop, value, receiver) {
@@ -235,15 +240,16 @@ class ManagedArray {
235
240
  throw new Error(`Cannot set ${String(prop)} on ${errorPath} because the record is not editable`);
236
241
  }
237
242
  if (prop === 'identifier') {
238
- // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
239
243
  self.identifier = value;
240
244
  return true;
241
245
  }
242
246
  if (prop === 'owner') {
243
- // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
244
247
  self.owner = value;
245
248
  return true;
246
249
  }
250
+ if (isExtensionProp(extensions, prop)) {
251
+ return performExtensionSet(receiver, extensions, signals, prop, value);
252
+ }
247
253
  const reflect = Reflect.set(target, prop, value, receiver);
248
254
  if (reflect) {
249
255
  if (!field.type) {
@@ -271,13 +277,36 @@ class ManagedArray {
271
277
  return Reflect.has(target, prop);
272
278
  }
273
279
  });
280
+
281
+ // we entangle the signal on the returned proxy since that is
282
+ // the object that other code will be interfacing with.
283
+ _SIGNAL = entangleSignal(signals, proxy, ARRAY_SIGNAL, undefined);
274
284
  return proxy;
275
285
  }
276
286
  }
287
+
288
+ // this will error if someone tries to call
289
+ // A(identifierArray) since it is not configurable
290
+ // which is preferable to the `meta` override we used
291
+ // before which required importing all of Ember
292
+ const desc = {
293
+ enumerable: true,
294
+ configurable: false,
295
+ get: function () {
296
+ // here to support computed chains
297
+ // and {{#each}}
298
+ if (macroCondition(getGlobalConfig().WarpDrive.deprecations.DEPRECATE_COMPUTED_CHAINS)) {
299
+ return this;
300
+ }
301
+ }
302
+ };
303
+ // compat(desc);
304
+ Object.defineProperty(ManagedArray.prototype, '[]', desc);
277
305
  const ObjectSymbols = new Set([OBJECT_SIGNAL, Parent, SOURCE, Editable, EmbeddedPath]);
278
306
 
279
307
  // const ignoredGlobalFields = new Set<string>(['setInterval', 'nodeType', 'nodeName', 'length', 'document', STRUCTURED]);
280
308
 
309
+ // eslint-disable-next-line @typescript-eslint/no-extraneous-class
281
310
  class ManagedObject {
282
311
  constructor(schema, cache, field, data, identifier, path, owner, editable, legacy) {
283
312
  // eslint-disable-next-line @typescript-eslint/no-this-alias
@@ -291,6 +320,9 @@ class ManagedObject {
291
320
  this[Legacy] = legacy;
292
321
  this[Parent] = identifier;
293
322
  this[EmbeddedPath] = path;
323
+
324
+ // prettier-ignore
325
+ const extensions = !legacy ? null : schema.CAUTION_MEGA_DANGER_ZONE_objectExtensions(field);
294
326
  const proxy = new Proxy(this[SOURCE], {
295
327
  ownKeys() {
296
328
  return Object.keys(self[SOURCE]);
@@ -328,11 +360,6 @@ class ManagedObject {
328
360
  return '<span>ManagedObject</span>';
329
361
  };
330
362
  }
331
- if (prop === 'toJSON') {
332
- return function () {
333
- return structuredClone(self[SOURCE]);
334
- };
335
- }
336
363
  if (_SIGNAL.isStale) {
337
364
  _SIGNAL.isStale = false;
338
365
  let newData = cache.getAttr(identifier, path);
@@ -346,10 +373,22 @@ class ManagedObject {
346
373
  }; // Add type assertion for newData
347
374
  }
348
375
  }
376
+
377
+ // toJSON and extensions need to come after we update data if stale
378
+ if (prop === 'toJSON') {
379
+ return function () {
380
+ return structuredClone(self[SOURCE]);
381
+ };
382
+ }
383
+
384
+ // we always defer to data before extensions
349
385
  if (prop in self[SOURCE]) {
350
386
  consumeInternalSignal(_SIGNAL);
351
387
  return self[SOURCE][prop];
352
388
  }
389
+ if (isExtensionProp(extensions, prop)) {
390
+ return performObjectExtensionGet(receiver, extensions, signals, prop);
391
+ }
353
392
  return Reflect.get(target, prop, receiver);
354
393
  },
355
394
  set(target, prop, value, receiver) {
@@ -358,6 +397,12 @@ class ManagedObject {
358
397
  throw new Error(`Cannot set read-only property '${String(prop)}' on ManagedObject`);
359
398
  }
360
399
  })(editable) : {};
400
+
401
+ // since objects function as dictionaries, we can't defer to schema/data before extensions
402
+ // unless the prop is in the existing data.
403
+ if (!(prop in self[SOURCE]) && isExtensionProp(extensions, prop)) {
404
+ return performExtensionSet(receiver, extensions, signals, prop, value);
405
+ }
361
406
  const reflect = Reflect.set(target, prop, value, receiver);
362
407
  if (!reflect) {
363
408
  return false;
@@ -553,7 +598,7 @@ function computeSchemaObject(store, cache, record, identifier, field, path, lega
553
598
  schemaObject = new ReactiveResource(store, identifier, {
554
599
  [Editable]: editable,
555
600
  [Legacy]: legacy
556
- }, true, field.type, embeddedPath);
601
+ }, true, field, embeddedPath);
557
602
  }
558
603
  if (!schemaObjectMapForRecord) {
559
604
  ManagedObjectMap.set(record, new Map([[field.name, schemaObject]]));
@@ -568,7 +613,6 @@ function computeAttribute(cache, identifier, prop, editable) {
568
613
  function computeDerivation(schema, record, identifier, field, prop) {
569
614
  return schema.derivation(field)(record, field.options ?? null, prop);
570
615
  }
571
-
572
616
  // TODO probably this should just be a Document
573
617
  // but its separate until we work out the lid situation
574
618
  class ResourceRelationship {
@@ -645,6 +689,7 @@ function computeHasMany(store, schema, cache, record, identifier, field, path, e
645
689
  type: field.type,
646
690
  identifier,
647
691
  cache,
692
+ field: legacy ? field : undefined,
648
693
  // we divorce the reference here because ManyArray mutates the target directly
649
694
  // before sending the mutation op to the cache. We may be able to avoid this in the future
650
695
  identifiers: rawValue.data?.slice(),
@@ -669,7 +714,7 @@ function computeHasMany(store, schema, cache, record, identifier, field, path, e
669
714
  return managedArray;
670
715
  }
671
716
  const IgnoredGlobalFields = new Set(['length', 'nodeType', 'then', 'setInterval', 'document', STRUCTURED]);
672
- const symbolList = [Destroy, RecordStore, Identifier, Editable, Parent, Checkout, Legacy, EmbeddedPath, EmbeddedType];
717
+ const symbolList = [Destroy, RecordStore, Identifier, Editable, Parent, Checkout, Legacy, EmbeddedPath, EmbeddedField];
673
718
  const RecordSymbols = new Set(symbolList);
674
719
  function isPathMatch(a, b) {
675
720
  return a.length === b.length && a.every((v, i) => v === b[i]);
@@ -690,24 +735,9 @@ const Editables = new WeakMap();
690
735
  * @hideconstructor
691
736
  * @public
692
737
  */
738
+ // eslint-disable-next-line @typescript-eslint/no-extraneous-class
693
739
  class ReactiveResource {
694
- /** @internal */
695
-
696
- /** @internal */
697
-
698
- /** @internal */
699
-
700
- /** @internal */
701
-
702
- /** @internal */
703
-
704
- /** @internal */
705
-
706
- /** @internal */
707
-
708
- /** @internal */
709
-
710
- constructor(store, identifier, Mode, isEmbedded = false, embeddedType = null, embeddedPath = null) {
740
+ constructor(store, identifier, Mode, isEmbedded = false, embeddedField = null, embeddedPath = null) {
711
741
  // eslint-disable-next-line @typescript-eslint/no-this-alias
712
742
  const self = this;
713
743
  this[RecordStore] = store;
@@ -720,15 +750,14 @@ class ReactiveResource {
720
750
  this[Legacy] = Mode[Legacy] ?? false;
721
751
  const schema = store.schema;
722
752
  const cache = store.cache;
723
- const identityField = schema.resource(isEmbedded ? {
724
- type: embeddedType
725
- } : identifier).identity;
753
+ const identityField = schema.resource(isEmbedded ? embeddedField : identifier).identity;
726
754
  const BoundFns = new Map();
727
- this[EmbeddedType] = embeddedType;
755
+
756
+ // prettier-ignore
757
+ const extensions = !Mode[Legacy] ? null : isEmbedded ? schema.CAUTION_MEGA_DANGER_ZONE_objectExtensions(embeddedField) : schema.CAUTION_MEGA_DANGER_ZONE_resourceExtensions(identifier);
758
+ this[EmbeddedField] = embeddedField;
728
759
  this[EmbeddedPath] = embeddedPath;
729
- const fields = isEmbedded ? schema.fields({
730
- type: embeddedType
731
- }) : schema.fields(identifier);
760
+ const fields = isEmbedded ? schema.fields(embeddedField) : schema.fields(identifier);
732
761
  const signals = withSignalStore(this);
733
762
  const proxy = new Proxy(this, {
734
763
  ownKeys() {
@@ -799,6 +828,12 @@ class ReactiveResource {
799
828
  },
800
829
  get(target, prop, receiver) {
801
830
  if (RecordSymbols.has(prop)) {
831
+ if (prop === Destroy) {
832
+ return () => _DESTROY(receiver);
833
+ }
834
+ if (prop === Checkout) {
835
+ return () => _CHECKOUT(receiver);
836
+ }
802
837
  return target[prop];
803
838
  }
804
839
  if (prop === Signals) {
@@ -880,11 +915,15 @@ class ReactiveResource {
880
915
  if (prop === 'constructor') {
881
916
  return ReactiveResource;
882
917
  }
918
+ if (isExtensionProp(extensions, prop)) {
919
+ return performObjectExtensionGet(receiver, extensions, signals, prop);
920
+ }
921
+
883
922
  // too many things check for random symbols
884
923
  if (typeof prop === 'symbol') return undefined;
885
924
  macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
886
925
  {
887
- throw new Error(`No field named ${String(prop)} on ${isEmbedded ? embeddedType : identifier.type}`);
926
+ throw new Error(`No field named ${String(prop)} on ${isEmbedded ? embeddedField.type : identifier.type}`);
888
927
  }
889
928
  })() : {};
890
929
  return undefined;
@@ -967,13 +1006,21 @@ class ReactiveResource {
967
1006
  },
968
1007
  set(target, prop, value, receiver) {
969
1008
  if (!IS_EDITABLE) {
970
- const type = isEmbedded ? embeddedType : identifier.type;
1009
+ const type = isEmbedded ? embeddedField.type : identifier.type;
971
1010
  throw new Error(`Cannot set ${String(prop)} on ${type} because the record is not editable`);
972
1011
  }
973
1012
  const maybeField = prop === identityField?.name ? identityField : fields.get(prop);
974
1013
  if (!maybeField) {
975
- const type = isEmbedded ? embeddedType : identifier.type;
976
- throw new Error(`There is no field named ${String(prop)} on ${type}`);
1014
+ const type = isEmbedded ? embeddedField.type : identifier.type;
1015
+ if (isExtensionProp(extensions, prop)) {
1016
+ return performExtensionSet(receiver, extensions, signals, prop, value);
1017
+ }
1018
+ macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
1019
+ {
1020
+ throw new Error(`There is no settable field named ${String(prop)} on ${type}`);
1021
+ }
1022
+ })() : {};
1023
+ return false;
977
1024
  }
978
1025
  const field = maybeField.kind === 'alias' ? maybeField.options : maybeField;
979
1026
  macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
@@ -1318,57 +1365,37 @@ class ReactiveResource {
1318
1365
  }
1319
1366
  return proxy;
1320
1367
  }
1321
-
1322
- /** @internal */
1323
- [Destroy]() {
1324
- if (this[Legacy]) {
1325
- // @ts-expect-error
1326
- this.isDestroying = true;
1327
- // @ts-expect-error
1328
- this.isDestroyed = true;
1329
- }
1330
- this[RecordStore].notifications.unsubscribe(this.___notifications);
1368
+ }
1369
+ function _CHECKOUT(record) {
1370
+ // IF we are already the editable record, throw an error
1371
+ if (record[Editable]) {
1372
+ throw new Error(`Cannot checkout an already editable record`);
1331
1373
  }
1332
-
1333
- /**
1334
- * Create an editable copy of the record
1335
- *
1336
- * ReactiveResource instances are not editable by default. This method creates an editable copy of the record. To use,
1337
- * import the `Checkout` symbol from `@warp-drive/schema-record` and call it on the record.
1338
- *
1339
- * ```ts
1340
- * import { Checkout } from '@warp-drive/schema-record';
1341
- *
1342
- * const record = store.peekRecord('user', '1');
1343
- * const editableRecord = await record[Checkout]();
1344
- * ```
1345
- *
1346
- * @returns a promise that resolves to the editable record
1347
- * @throws if the record is already editable or if the record is embedded
1348
- *
1349
- */
1350
- [Checkout]() {
1351
- // IF we are already the editable record, throw an error
1352
- if (this[Editable]) {
1353
- throw new Error(`Cannot checkout an already editable record`);
1354
- }
1355
- const editable = Editables.get(this);
1356
- if (editable) {
1357
- return Promise.resolve(editable);
1358
- }
1359
- const embeddedType = this[EmbeddedType];
1360
- const embeddedPath = this[EmbeddedPath];
1361
- const isEmbedded = embeddedType !== null && embeddedPath !== null;
1362
- if (isEmbedded) {
1363
- throw new Error(`Cannot checkout an embedded record (yet)`);
1364
- }
1365
- const editableRecord = new ReactiveResource(this[RecordStore], this[Identifier], {
1366
- [Editable]: true,
1367
- [Legacy]: this[Legacy]
1368
- }, isEmbedded, embeddedType, embeddedPath);
1369
- setRecordIdentifier(editableRecord, recordIdentifierFor(this));
1370
- return Promise.resolve(editableRecord);
1374
+ const editable = Editables.get(record);
1375
+ if (editable) {
1376
+ return Promise.resolve(editable);
1377
+ }
1378
+ const embeddedType = record[EmbeddedField];
1379
+ const embeddedPath = record[EmbeddedPath];
1380
+ const isEmbedded = embeddedType !== null && embeddedPath !== null;
1381
+ if (isEmbedded) {
1382
+ throw new Error(`Cannot checkout an embedded record (yet)`);
1371
1383
  }
1384
+ const editableRecord = new ReactiveResource(record[RecordStore], record[Identifier], {
1385
+ [Editable]: true,
1386
+ [Legacy]: record[Legacy]
1387
+ }, isEmbedded, embeddedType, embeddedPath);
1388
+ setRecordIdentifier(editableRecord, recordIdentifierFor(record));
1389
+ return Promise.resolve(editableRecord);
1390
+ }
1391
+ function _DESTROY(record) {
1392
+ if (record[Legacy]) {
1393
+ // @ts-expect-error
1394
+ record.isDestroying = true;
1395
+ // @ts-expect-error
1396
+ record.isDestroyed = true;
1397
+ }
1398
+ record[RecordStore].notifications.unsubscribe(record.___notifications);
1372
1399
  }
1373
1400
  function instantiateRecord(store, identifier, createArgs) {
1374
1401
  const schema = store.schema;
@@ -1438,6 +1465,139 @@ function _constructor(record) {
1438
1465
  }
1439
1466
  _constructor[Type] = '@constructor';
1440
1467
 
1468
+ /**
1469
+ * Extensions allow providing non-schema driven behaviors to
1470
+ * reactive resources and arrays.
1471
+ */
1472
+
1473
+ const BannedKeys = ['constructor', '__proto__'];
1474
+ function processExtension(extension) {
1475
+ const {
1476
+ kind,
1477
+ name
1478
+ } = extension;
1479
+ const features = new Map();
1480
+ const baseFeatures = typeof extension.features === 'function' ? extension.features.prototype : extension.features;
1481
+ for (const key of Object.getOwnPropertyNames(baseFeatures)) {
1482
+ if (BannedKeys.includes(key)) continue;
1483
+ const decl = Object.getOwnPropertyDescriptor(baseFeatures, key);
1484
+ macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
1485
+ if (!test) {
1486
+ throw new Error(`Expected to find a declaration for ${key} on extension ${name}`);
1487
+ }
1488
+ })(decl) : {};
1489
+ if (decl.value) {
1490
+ const {
1491
+ value
1492
+ } = decl;
1493
+ features.set(key, typeof value === 'function' ? {
1494
+ kind: 'method',
1495
+ fn: value
1496
+ } : decl.writable ? {
1497
+ kind: 'mutable-value',
1498
+ value
1499
+ } : {
1500
+ kind: 'readonly-value',
1501
+ value
1502
+ });
1503
+ continue;
1504
+ }
1505
+ if (decl.get || decl.set) {
1506
+ const {
1507
+ get,
1508
+ set
1509
+ } = decl;
1510
+ features.set(key,
1511
+ // prettier-ignore
1512
+ get && set ? {
1513
+ kind: 'mutable-field',
1514
+ get,
1515
+ set
1516
+ } : get ? {
1517
+ kind: 'readonly-field',
1518
+ get
1519
+ } : {
1520
+ kind: 'writeonly-field',
1521
+ set: set
1522
+ });
1523
+ continue;
1524
+ }
1525
+ macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
1526
+ {
1527
+ throw new Error(`The feature ${key} on extension ${name} is of an unknown variety.`);
1528
+ }
1529
+ })() : {};
1530
+ }
1531
+ return {
1532
+ kind,
1533
+ name,
1534
+ features
1535
+ };
1536
+ }
1537
+ function getExt(extCache, type, extName) {
1538
+ const ext = extCache[type].get(extName);
1539
+ macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
1540
+ if (!test) {
1541
+ throw new Error(`expected to have an extension named ${String(extName)} available for ${type}s`);
1542
+ }
1543
+ })(ext) : {};
1544
+ return ext?.features ?? null;
1545
+ }
1546
+ function hasObjectSchema(field) {
1547
+ return 'kind' in field && (field.kind === 'schema-array' || field.kind === 'schema-object');
1548
+ }
1549
+ function processExtensions(schema, field, scenario) {
1550
+ // if we're looking up extensions for a resource, there is no
1551
+ // merging required so if we have no objectExtensions
1552
+ // we are done.
1553
+ if (scenario === 'resource') {
1554
+ if (!('objectExtensions' in field || !field.objectExtensions?.length)) {
1555
+ return null;
1556
+ }
1557
+ }
1558
+ const type = scenario === 'resource' ? 'object' : scenario;
1559
+ const extCache = schema._extensions;
1560
+ const fieldCache = schema._cachedFieldExtensionsByField;
1561
+ if (fieldCache[type].has(field)) {
1562
+ return fieldCache[type].get(field);
1563
+ }
1564
+
1565
+ // prettier-ignore
1566
+ const extensions = (scenario === 'resource' ? field.objectExtensions : scenario === 'object' ? field.options?.objectExtensions : field.options?.arrayExtensions) || null;
1567
+
1568
+ // if we are a resource scenario, we know from the first check we do have extensions
1569
+ // if we are an object scenario, we can now return the resource scenario.
1570
+ // if we are an array scenario, there is nothing more to process.
1571
+ if (!extensions) {
1572
+ if (scenario === 'array') return null;
1573
+ if (!hasObjectSchema(field)) {
1574
+ return null;
1575
+ }
1576
+ return schema.CAUTION_MEGA_DANGER_ZONE_resourceExtensions(field);
1577
+ }
1578
+
1579
+ // if we have made it here, we have extensions, lets check if there's
1580
+ // a cached version we can use
1581
+ const baseExtensions = scenario === 'resource' && hasObjectSchema(field) ? schema.CAUTION_MEGA_DANGER_ZONE_resourceExtensions(field) : scenario === 'object' && hasObjectSchema(field) ? schema.CAUTION_MEGA_DANGER_ZONE_resourceExtensions(field) : null;
1582
+ if (!baseExtensions && extensions.length === 1) {
1583
+ const value = getExt(extCache, type, extensions[0]);
1584
+ fieldCache[type].set(field, value);
1585
+ return value;
1586
+ }
1587
+ const features = new Map(baseExtensions);
1588
+ for (const extName of extensions) {
1589
+ const value = getExt(extCache, type, extName);
1590
+ if (value) {
1591
+ for (const [feature, desc] of value) {
1592
+ features.set(feature, desc);
1593
+ }
1594
+ }
1595
+ }
1596
+ const value = features.size ? features : null;
1597
+ fieldCache[type].set(field, value);
1598
+ return value;
1599
+ }
1600
+
1441
1601
  /**
1442
1602
  * Utility for constructing a ResourceSchema with the recommended
1443
1603
  * fields for the PolarisMode experience.
@@ -1464,7 +1624,6 @@ function withDefaults(schema) {
1464
1624
  schema.fields.push(ConstructorField);
1465
1625
  return schema;
1466
1626
  }
1467
-
1468
1627
  /**
1469
1628
  * A derivation that computes its value from the
1470
1629
  * record's identity.
@@ -1486,8 +1645,7 @@ function withDefaults(schema) {
1486
1645
  *
1487
1646
  * @public
1488
1647
  */
1489
-
1490
- function fromIdentity(record, options, key) {
1648
+ const fromIdentity = (record, options, key) => {
1491
1649
  const identifier = record[Identifier];
1492
1650
  macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
1493
1651
  if (!test) {
@@ -1500,7 +1658,7 @@ function fromIdentity(record, options, key) {
1500
1658
  }
1501
1659
  })(options?.key && ['lid', 'id', 'type', '^'].includes(options.key)) : {};
1502
1660
  return options.key === '^' ? identifier : identifier[options.key];
1503
- }
1661
+ };
1504
1662
  fromIdentity[Type] = '@identity';
1505
1663
 
1506
1664
  /**
@@ -1559,6 +1717,8 @@ class SchemaService {
1559
1717
 
1560
1718
  /** @internal */
1561
1719
 
1720
+ /** @internal */
1721
+
1562
1722
  constructor() {
1563
1723
  this._schemas = new Map();
1564
1724
  this._transforms = new Map();
@@ -1566,6 +1726,14 @@ class SchemaService {
1566
1726
  this._derivations = new Map();
1567
1727
  this._traits = new Set();
1568
1728
  this._modes = new Map();
1729
+ this._extensions = {
1730
+ object: new Map(),
1731
+ array: new Map()
1732
+ };
1733
+ this._cachedFieldExtensionsByField = {
1734
+ object: new Map(),
1735
+ array: new Map()
1736
+ };
1569
1737
  }
1570
1738
  resourceTypes() {
1571
1739
  return Array.from(this._schemas.keys());
@@ -1687,6 +1855,24 @@ class SchemaService {
1687
1855
  registerDerivation(derivation) {
1688
1856
  this._derivations.set(derivation[Type], makeCachedDerivation(derivation));
1689
1857
  }
1858
+ CAUTION_MEGA_DANGER_ZONE_registerExtension(extension) {
1859
+ macroCondition(getGlobalConfig().WarpDrive.env.DEBUG) ? (test => {
1860
+ if (!test) {
1861
+ throw new Error(`an extension named ${extension.name} for ${extension.kind} already exists!`);
1862
+ }
1863
+ })(!this._extensions[extension.kind].has(extension.name)) : {};
1864
+ this._extensions[extension.kind].set(extension.name, processExtension(extension));
1865
+ }
1866
+ CAUTION_MEGA_DANGER_ZONE_resourceExtensions(resource) {
1867
+ const schema = this.resource(resource);
1868
+ return processExtensions(this, schema, 'resource');
1869
+ }
1870
+ CAUTION_MEGA_DANGER_ZONE_objectExtensions(field) {
1871
+ return processExtensions(this, field, 'object');
1872
+ }
1873
+ CAUTION_MEGA_DANGER_ZONE_arrayExtensions(field) {
1874
+ return processExtensions(this, field, 'array');
1875
+ }
1690
1876
 
1691
1877
  /**
1692
1878
  * This is an internal method used to register behaviors for legacy mode.
@@ -1704,7 +1890,7 @@ class SchemaService {
1704
1890
  if (!test) {
1705
1891
  throw new Error(`Mode '${mode}' is already registered`);
1706
1892
  }
1707
- })(!this._traits.has(mode)) : {};
1893
+ })(!this._modes.has(mode)) : {};
1708
1894
  this._modes.set(mode, kinds);
1709
1895
  }
1710
1896