@cldmv/slothlet 3.3.0 → 3.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 (139) hide show
  1. package/README.md +9 -10
  2. package/REFERENCE.md +23 -0
  3. package/dist/lib/builders/api-assignment.mjs +1 -589
  4. package/dist/lib/builders/api_builder.mjs +1 -1385
  5. package/dist/lib/builders/builder.mjs +1 -78
  6. package/dist/lib/builders/modes-processor.mjs +1 -1800
  7. package/dist/lib/errors.mjs +9 -211
  8. package/dist/lib/factories/component-base.mjs +1 -80
  9. package/dist/lib/factories/context.mjs +1 -22
  10. package/dist/lib/handlers/api-cache-manager.mjs +1 -200
  11. package/dist/lib/handlers/api-manager.mjs +1 -2536
  12. package/dist/lib/handlers/context-async.mjs +1 -172
  13. package/dist/lib/handlers/context-live.mjs +1 -173
  14. package/dist/lib/handlers/hook-manager.mjs +1 -667
  15. package/dist/lib/handlers/lifecycle-token.mjs +1 -28
  16. package/dist/lib/handlers/lifecycle.mjs +1 -115
  17. package/dist/lib/handlers/materialize-manager.mjs +1 -48
  18. package/dist/lib/handlers/metadata.mjs +1 -501
  19. package/dist/lib/handlers/ownership.mjs +1 -322
  20. package/dist/lib/handlers/permission-manager.mjs +1 -392
  21. package/dist/lib/handlers/unified-wrapper.mjs +1 -3110
  22. package/dist/lib/handlers/version-manager.mjs +1 -885
  23. package/dist/lib/helpers/class-instance-wrapper.mjs +1 -109
  24. package/dist/lib/helpers/config.mjs +1 -439
  25. package/dist/lib/helpers/eventemitter-context.mjs +1 -349
  26. package/dist/lib/helpers/hint-detector.mjs +1 -47
  27. package/dist/lib/helpers/modes-utils.mjs +1 -37
  28. package/dist/lib/helpers/pattern-matcher.mjs +1 -125
  29. package/dist/lib/helpers/resolve-from-caller.mjs +1 -169
  30. package/dist/lib/helpers/sanitize.mjs +1 -340
  31. package/dist/lib/helpers/utilities.mjs +1 -70
  32. package/dist/lib/i18n/languages/de-de.json +1 -0
  33. package/dist/lib/i18n/languages/en-gb.json +1 -0
  34. package/dist/lib/i18n/languages/en-us.json +1 -0
  35. package/dist/lib/i18n/languages/es-es.json +412 -0
  36. package/dist/lib/i18n/languages/es-mx.json +1 -0
  37. package/dist/lib/i18n/languages/fr-fr.json +1 -0
  38. package/dist/lib/i18n/languages/hi-in.json +2 -1
  39. package/dist/lib/i18n/languages/ja-jp.json +1 -0
  40. package/dist/lib/i18n/languages/ko-kr.json +1 -0
  41. package/dist/lib/i18n/languages/pt-br.json +21 -20
  42. package/dist/lib/i18n/languages/ru-ru.json +2 -1
  43. package/dist/lib/i18n/languages/zh-cn.json +6 -5
  44. package/dist/lib/i18n/translations.mjs +1 -126
  45. package/dist/lib/modes/eager.mjs +1 -59
  46. package/dist/lib/modes/lazy.mjs +1 -81
  47. package/dist/lib/processors/flatten.mjs +1 -437
  48. package/dist/lib/processors/loader.mjs +1 -339
  49. package/dist/lib/processors/type-generator.mjs +1 -275
  50. package/dist/lib/processors/typescript.mjs +1 -172
  51. package/dist/lib/runtime/runtime-asynclocalstorage.mjs +1 -113
  52. package/dist/lib/runtime/runtime-livebindings.mjs +1 -78
  53. package/dist/lib/runtime/runtime.mjs +1 -102
  54. package/dist/slothlet.mjs +1 -817
  55. package/package.json +35 -31
  56. package/types/dist/lib/builders/api-assignment.d.mts +3 -92
  57. package/types/dist/lib/builders/api-assignment.d.mts.map +1 -1
  58. package/types/dist/lib/builders/api_builder.d.mts +102 -91
  59. package/types/dist/lib/builders/api_builder.d.mts.map +1 -1
  60. package/types/dist/lib/builders/builder.d.mts +1 -55
  61. package/types/dist/lib/builders/builder.d.mts.map +1 -1
  62. package/types/dist/lib/builders/modes-processor.d.mts +3 -27
  63. package/types/dist/lib/builders/modes-processor.d.mts.map +1 -1
  64. package/types/dist/lib/errors.d.mts +19 -109
  65. package/types/dist/lib/errors.d.mts.map +1 -1
  66. package/types/dist/lib/factories/component-base.d.mts +7 -177
  67. package/types/dist/lib/factories/component-base.d.mts.map +1 -1
  68. package/types/dist/lib/factories/context.d.mts +4 -22
  69. package/types/dist/lib/factories/context.d.mts.map +1 -1
  70. package/types/dist/lib/handlers/api-cache-manager.d.mts +20 -203
  71. package/types/dist/lib/handlers/api-cache-manager.d.mts.map +1 -1
  72. package/types/dist/lib/handlers/api-manager.d.mts +34 -408
  73. package/types/dist/lib/handlers/api-manager.d.mts.map +1 -1
  74. package/types/dist/lib/handlers/context-async.d.mts +23 -61
  75. package/types/dist/lib/handlers/context-async.d.mts.map +1 -1
  76. package/types/dist/lib/handlers/context-live.d.mts +22 -59
  77. package/types/dist/lib/handlers/context-live.d.mts.map +1 -1
  78. package/types/dist/lib/handlers/hook-manager.d.mts +46 -185
  79. package/types/dist/lib/handlers/hook-manager.d.mts.map +1 -1
  80. package/types/dist/lib/handlers/lifecycle-token.d.mts +3 -48
  81. package/types/dist/lib/handlers/lifecycle-token.d.mts.map +1 -1
  82. package/types/dist/lib/handlers/lifecycle.d.mts +5 -82
  83. package/types/dist/lib/handlers/lifecycle.d.mts.map +1 -1
  84. package/types/dist/lib/handlers/materialize-manager.d.mts +8 -70
  85. package/types/dist/lib/handlers/materialize-manager.d.mts.map +1 -1
  86. package/types/dist/lib/handlers/metadata.d.mts +17 -221
  87. package/types/dist/lib/handlers/metadata.d.mts.map +1 -1
  88. package/types/dist/lib/handlers/ownership.d.mts +44 -160
  89. package/types/dist/lib/handlers/ownership.d.mts.map +1 -1
  90. package/types/dist/lib/handlers/permission-manager.d.mts +40 -141
  91. package/types/dist/lib/handlers/permission-manager.d.mts.map +1 -1
  92. package/types/dist/lib/handlers/unified-wrapper.d.mts +26 -239
  93. package/types/dist/lib/handlers/unified-wrapper.d.mts.map +1 -1
  94. package/types/dist/lib/handlers/version-manager.d.mts +28 -225
  95. package/types/dist/lib/handlers/version-manager.d.mts.map +1 -1
  96. package/types/dist/lib/helpers/class-instance-wrapper.d.mts +2 -52
  97. package/types/dist/lib/helpers/class-instance-wrapper.d.mts.map +1 -1
  98. package/types/dist/lib/helpers/config.d.mts +125 -139
  99. package/types/dist/lib/helpers/config.d.mts.map +1 -1
  100. package/types/dist/lib/helpers/eventemitter-context.d.mts +3 -29
  101. package/types/dist/lib/helpers/eventemitter-context.d.mts.map +1 -1
  102. package/types/dist/lib/helpers/hint-detector.d.mts +2 -15
  103. package/types/dist/lib/helpers/hint-detector.d.mts.map +1 -1
  104. package/types/dist/lib/helpers/modes-utils.d.mts +3 -30
  105. package/types/dist/lib/helpers/modes-utils.d.mts.map +1 -1
  106. package/types/dist/lib/helpers/pattern-matcher.d.mts +3 -43
  107. package/types/dist/lib/helpers/pattern-matcher.d.mts.map +1 -1
  108. package/types/dist/lib/helpers/resolve-from-caller.d.mts +3 -27
  109. package/types/dist/lib/helpers/resolve-from-caller.d.mts.map +1 -1
  110. package/types/dist/lib/helpers/sanitize.d.mts +4 -92
  111. package/types/dist/lib/helpers/sanitize.d.mts.map +1 -1
  112. package/types/dist/lib/helpers/utilities.d.mts +4 -52
  113. package/types/dist/lib/helpers/utilities.d.mts.map +1 -1
  114. package/types/dist/lib/i18n/translations.d.mts +4 -37
  115. package/types/dist/lib/i18n/translations.d.mts.map +1 -1
  116. package/types/dist/lib/modes/eager.d.mts +8 -30
  117. package/types/dist/lib/modes/eager.d.mts.map +1 -1
  118. package/types/dist/lib/modes/lazy.d.mts +10 -43
  119. package/types/dist/lib/modes/lazy.d.mts.map +1 -1
  120. package/types/dist/lib/processors/flatten.d.mts +56 -107
  121. package/types/dist/lib/processors/flatten.d.mts.map +1 -1
  122. package/types/dist/lib/processors/loader.d.mts +6 -41
  123. package/types/dist/lib/processors/loader.d.mts.map +1 -1
  124. package/types/dist/lib/processors/type-generator.d.mts +2 -16
  125. package/types/dist/lib/processors/type-generator.d.mts.map +1 -1
  126. package/types/dist/lib/processors/typescript.d.mts +6 -53
  127. package/types/dist/lib/processors/typescript.d.mts.map +1 -1
  128. package/types/dist/lib/runtime/runtime-asynclocalstorage.d.mts +3 -71
  129. package/types/dist/lib/runtime/runtime-asynclocalstorage.d.mts.map +1 -1
  130. package/types/dist/lib/runtime/runtime-livebindings.d.mts +2 -37
  131. package/types/dist/lib/runtime/runtime-livebindings.d.mts.map +1 -1
  132. package/types/dist/lib/runtime/runtime.d.mts +3 -39
  133. package/types/dist/lib/runtime/runtime.d.mts.map +1 -1
  134. package/types/dist/slothlet.d.mts +3 -249
  135. package/types/dist/slothlet.d.mts.map +1 -1
  136. package/types/index.d.mts +36 -16
  137. package/types/index.d.mts.map +1 -0
  138. package/AGENT-USAGE.md +0 -736
  139. package/docs/API-RULES.md +0 -712
@@ -14,592 +14,4 @@
14
14
  limitations under the License.
15
15
  */
16
16
 
17
-
18
-
19
-
20
- import { ComponentBase } from "@cldmv/slothlet/factories/component-base";
21
- import { resolveWrapper } from "@cldmv/slothlet/handlers/unified-wrapper";
22
-
23
-
24
- export class ApiAssignment extends ComponentBase {
25
- static slothletProperty = "apiAssignment";
26
-
27
-
28
- constructor(slothlet) {
29
- super(slothlet);
30
- }
31
-
32
-
33
- isWrapperProxy(value) {
34
- return !!(value && resolveWrapper(value));
35
- }
36
-
37
-
38
- assignToApiPath(targetApi, key, value, options = {}) {
39
- const valueIsWrapper = this.isWrapperProxy(value);
40
-
41
-
42
- const valueId = valueIsWrapper ? (resolveWrapper(value)?.____slothletInternal?.id ?? "no-id") : "not-wrapper";
43
- this.slothlet.debug("api", {
44
- key: "DEBUG_MODE_ASSIGN_TO_API",
45
- propKey: key,
46
- valueId,
47
- typeOf: typeof value
48
- });
49
-
50
- const {
51
- allowOverwrite = false,
52
- mutateExisting = false,
53
- useCollisionDetection = false,
54
- config = null,
55
- collisionContext = "initial",
56
- syncWrapper = null,
57
- collisionMode = "merge",
58
- moduleID = null
59
- } = options;
60
-
61
-
62
- const existing = targetApi[key];
63
-
64
-
65
- if (existing !== undefined && this.isWrapperProxy(existing) && this.isWrapperProxy(value)) {
66
- if (mutateExisting && syncWrapper) {
67
- syncWrapper(existing, value, config, collisionMode, moduleID);
68
- return true;
69
- }
70
-
71
- }
72
-
73
-
74
- this.slothlet.debug("api", {
75
- key: "DEBUG_MODE_COLLISION_CHECK",
76
- propKey: key,
77
- useCollisionDetection,
78
- hasConfig: !!config,
79
- hasExisting: existing !== undefined,
80
- existingType: typeof existing
81
- });
82
- if (useCollisionDetection && config && existing !== undefined) {
83
- this.slothlet.debug("api", {
84
- key: "DEBUG_MODE_COLLISION_DETECT",
85
- propKey: key,
86
- context: collisionContext,
87
- existingType: typeof existing,
88
- valueType: typeof value
89
- });
90
-
91
- const collisionMode = config.collision?.[collisionContext] || "merge";
92
-
93
- if (collisionMode === "error") {
94
-
95
-
96
- const SlothletError = this.slothlet?.SlothletError || Error;
97
- throw new SlothletError("COLLISION_ERROR", {
98
- key: String(key),
99
- collisionMode,
100
- collisionContext
101
- });
102
- }
103
-
104
- if (collisionMode === "skip") {
105
-
106
- return false;
107
- }
108
-
109
-
110
- let effectiveMode = collisionMode;
111
- if (collisionMode === "warn") {
112
- new this.slothlet.SlothletWarning("WARNING_COLLISION_FILE_FOLDER_MERGE", {
113
- key: String(key)
114
- });
115
-
116
- effectiveMode = "merge";
117
- }
118
-
119
-
120
-
121
- const existingIsWrapper = this.isWrapperProxy(existing);
122
- const valueIsWrapper = this.isWrapperProxy(value);
123
-
124
- this.slothlet.debug("api", {
125
- key: "DEBUG_MODE_COLLISION_WRAPPER_DETECTION",
126
- propKey: key,
127
- existingIsWrapper,
128
- valueIsWrapper,
129
- hasExistingWrapper: resolveWrapper(existing) ? "yes" : "no",
130
- hasValueWrapper: resolveWrapper(value) ? "yes" : "no"
131
- });
132
-
133
- if (existingIsWrapper && valueIsWrapper) {
134
- const existingWrapper = resolveWrapper(existing);
135
- const valueWrapper = resolveWrapper(value);
136
- const existingIsLazyUnmaterialized =
137
- existingWrapper.____slothletInternal.mode === "lazy" && !existingWrapper.____slothletInternal.state.materialized;
138
- const valueIsLazyUnmaterialized =
139
- valueWrapper.____slothletInternal.mode === "lazy" && !valueWrapper.____slothletInternal.state.materialized;
140
-
141
- this.slothlet.debug("api", {
142
- key: "DEBUG_MODE_COLLISION_LAZY_DETECTION",
143
- propKey: key,
144
- effectiveMode,
145
- existingLazy: existingIsLazyUnmaterialized,
146
- valueLazy: valueIsLazyUnmaterialized
147
- });
148
-
149
-
150
-
151
-
152
- if (existingIsLazyUnmaterialized) {
153
- this.slothlet.debug("api", {
154
- key: "DEBUG_MODE_COLLISION_SET_MODE_EXISTING_WRAPPER",
155
- effectiveMode,
156
- apiPath: existingWrapper.____slothletInternal.apiPath
157
- });
158
- existingWrapper.____slothletInternal.state.collisionMode = effectiveMode;
159
- this.slothlet.debug("api", {
160
- key: "DEBUG_MODE_COLLISION_VERIFIED_EXISTING_WRAPPER_MODE",
161
- collisionMode: existingWrapper.____slothletInternal.state.collisionMode
162
- });
163
- }
164
- if (valueIsLazyUnmaterialized) {
165
- this.slothlet.debug("api", {
166
- key: "DEBUG_MODE_COLLISION_SET_MODE_VALUE_WRAPPER",
167
- effectiveMode,
168
- apiPath: valueWrapper.____slothletInternal.apiPath
169
- });
170
- valueWrapper.____slothletInternal.state.collisionMode = effectiveMode;
171
- this.slothlet.debug("api", {
172
- key: "DEBUG_MODE_COLLISION_VERIFIED_VALUE_WRAPPER_MODE",
173
- collisionMode: valueWrapper.____slothletInternal.state.collisionMode
174
- });
175
-
176
-
177
-
178
- if (effectiveMode === "replace") {
179
- this.slothlet.debug("api", {
180
- key: "DEBUG_MODE_COLLISION_REPLACE_MATERIALIZE",
181
- apiPath: valueWrapper.____slothletInternal.apiPath
182
- });
183
- valueWrapper._materialize();
184
- }
185
- }
186
- }
187
-
188
-
189
- if (effectiveMode === "replace") {
190
-
191
-
192
-
193
- if (existingIsWrapper && valueIsWrapper) {
194
- const existingWrapper = resolveWrapper(existing);
195
- const valueWrapper = resolveWrapper(value);
196
-
197
-
198
-
199
-
200
- const existingIsLazyUnmaterialized =
201
- existingWrapper.____slothletInternal.mode === "lazy" && !existingWrapper.____slothletInternal.state.materialized;
202
- const valueIsLazyUnmaterialized =
203
- valueWrapper.____slothletInternal.mode === "lazy" && !valueWrapper.____slothletInternal.state.materialized;
204
-
205
-
206
- if (valueIsLazyUnmaterialized && !existingIsLazyUnmaterialized) {
207
- this.slothlet.debug("api", {
208
- key: "DEBUG_MODE_COLLISION_REPLACE_NO_COPY"
209
- });
210
- this.slothlet.debug("api", {
211
- key: "DEBUG_MODE_COLLISION_REPLACE_BEFORE",
212
- propKey: key,
213
- currentWrapperId: resolveWrapper(existing)?.____slothletInternal.id
214
- });
215
- this.slothlet.debug("api", {
216
- key: "DEBUG_MODE_COLLISION_ASSIGN_REPLACING_WITH_LAZY",
217
- propKey: key,
218
- collisionMode: valueWrapper.____slothletInternal.state.collisionMode
219
- });
220
- targetApi[key] = value;
221
- this.slothlet.debug("api", {
222
- key: "DEBUG_MODE_COLLISION_REPLACE_AFTER",
223
- propKey: key,
224
- newWrapperId: resolveWrapper(targetApi[key])?.____slothletInternal.id
225
- });
226
- this.slothlet.debug("api", {
227
- key: "DEBUG_MODE_COLLISION_REPLACE_VERIFY",
228
- expectedId: valueWrapper.____slothletInternal.id,
229
- actualId: resolveWrapper(targetApi[key])?.____slothletInternal.id
230
- });
231
- return true;
232
- }
233
-
234
- }
235
-
236
- targetApi[key] = value;
237
- return true;
238
- }
239
-
240
-
241
-
242
-
243
- if (effectiveMode === "merge" || effectiveMode === "merge-replace") {
244
- const isMergeReplace = effectiveMode === "merge-replace";
245
-
246
-
247
- if (existingIsWrapper && valueIsWrapper) {
248
-
249
- const existingWrapper = resolveWrapper(existing);
250
- const valueWrapper = resolveWrapper(value);
251
-
252
-
253
-
254
- const existingIsLazyUnmaterialized =
255
- existingWrapper.____slothletInternal.mode === "lazy" && !existingWrapper.____slothletInternal.state.materialized;
256
- const valueIsLazyUnmaterialized =
257
- valueWrapper.____slothletInternal.mode === "lazy" && !valueWrapper.____slothletInternal.state.materialized;
258
-
259
- if (existingIsLazyUnmaterialized && !valueIsLazyUnmaterialized) {
260
-
261
-
262
-
263
-
264
- const valueMetadata = this.slothlet.handlers?.metadata?.getMetadata(value);
265
- const valueFilePath = valueMetadata?.filePath;
266
-
267
-
268
-
269
-
270
-
271
-
272
- if (!existingWrapper.____slothletInternal.childFilePathsPreMaterialize) {
273
- existingWrapper.____slothletInternal.childFilePathsPreMaterialize = {};
274
- }
275
-
276
- const valueChildKeys = Object.keys(valueWrapper).filter((k) => !k.startsWith("_") && !k.startsWith("__"));
277
- for (const key of valueChildKeys) {
278
-
279
- Object.defineProperty(existingWrapper, key, {
280
- configurable: true
281
- });
282
-
283
- if (valueFilePath) {
284
- existingWrapper.____slothletInternal.childFilePathsPreMaterialize[key] = valueFilePath;
285
- }
286
- }
287
-
288
- return true;
289
- } else if (valueIsLazyUnmaterialized && !existingIsLazyUnmaterialized) {
290
-
291
-
292
-
293
-
294
-
295
-
296
-
297
-
298
-
299
- if (!isMergeReplace) {
300
-
301
-
302
-
303
-
304
- const existingMetadata = this.slothlet.handlers?.metadata?.getMetadata(existing);
305
- const existingFilePath = existingMetadata?.filePath;
306
-
307
-
308
- if (!valueWrapper.____slothletInternal.childFilePathsPreMaterialize) {
309
- valueWrapper.____slothletInternal.childFilePathsPreMaterialize = {};
310
- }
311
-
312
- const existingChildKeys = Object.keys(existingWrapper).filter((k) => !k.startsWith("_") && !k.startsWith("__"));
313
-
314
-
315
-
316
- this.slothlet.debug("api", {
317
- key: "DEBUG_MODE_COLLISION_COPY_CHILD_KEYS",
318
- existingChildKeys: existingChildKeys.join(","),
319
- fromApiPath: existingWrapper.____slothletInternal.apiPath,
320
- toApiPath: valueWrapper.____slothletInternal.apiPath,
321
- valueWrapperId: valueWrapper.____slothletInternal.id || "no-id"
322
- });
323
-
324
-
325
- if (!valueWrapper.____slothletInternal.collisionMergedKeys) {
326
- valueWrapper.____slothletInternal.collisionMergedKeys = new Set();
327
- }
328
-
329
- for (const key of existingChildKeys) {
330
- const child = existingWrapper[key];
331
- this.slothlet.debug("api", {
332
- key: "DEBUG_MODE_COLLISION_COPY_INDIVIDUAL_KEY",
333
- propKey: key,
334
- childName: child?.name,
335
- typeOf: typeof child,
336
- valueWrapperId: valueWrapper.____slothletInternal.id || "no-id"
337
- });
338
- Object.defineProperty(valueWrapper, key, {
339
- value: child,
340
- writable: false,
341
- enumerable: true,
342
- configurable: true
343
- });
344
-
345
- valueWrapper.____slothletInternal.collisionMergedKeys.add(key);
346
-
347
- if (existingFilePath) {
348
- valueWrapper.____slothletInternal.childFilePathsPreMaterialize[key] = existingFilePath;
349
- }
350
- }
351
-
352
-
353
-
354
-
355
-
356
- this.slothlet.debug("api", {
357
- key: "DEBUG_MODE_COLLISION_TRIGGER_EARLY_MAT",
358
- apiPath: valueWrapper.____slothletInternal.apiPath
359
- });
360
- valueWrapper.____slothletInternal.needsImmediateChildAdoption = true;
361
- if (
362
- valueWrapper.____slothletInternal.materializeFunc &&
363
- !valueWrapper.____slothletInternal.state?.materialized &&
364
- !valueWrapper.____slothletInternal.state?.inFlight
365
- ) {
366
- valueWrapper._materialize().catch((err) => {
367
- new this.slothlet.SlothletWarning(
368
- "WARNING_COLLISION_TRIGGER_MATERIALIZE_ERROR",
369
- {
370
- apiPath: valueWrapper.____slothletInternal.apiPath
371
- },
372
- err
373
- );
374
- });
375
- }
376
-
377
- } else {
378
-
379
-
380
-
381
-
382
- valueWrapper._mergeAfterMaterialize = {
383
- existingWrapper,
384
- isMergeReplace: true
385
- };
386
- }
387
-
388
-
389
- this.slothlet.debug("api", {
390
- key: "DEBUG_MODE_COLLISION_ASSIGN_REPLACING_WITH_LAZY",
391
- propKey: key,
392
- collisionMode: valueWrapper.____slothletInternal.state.collisionMode
393
- });
394
- targetApi[key] = value;
395
- return true;
396
- }
397
-
398
-
399
-
400
- const existingChildCount = Object.keys(existingWrapper).filter((k) => !k.startsWith("_") && !k.startsWith("__")).length;
401
- const valueChildCount = Object.keys(valueWrapper).filter((k) => !k.startsWith("_") && !k.startsWith("__")).length;
402
- if (existingWrapper.____slothletInternal.impl && existingChildCount === 0) {
403
- existingWrapper.___adoptImplChildren();
404
- }
405
- if (valueWrapper.____slothletInternal.impl && valueChildCount === 0) {
406
- valueWrapper.___adoptImplChildren();
407
- }
408
-
409
-
410
-
411
-
412
-
413
-
414
-
415
- const valueChildKeys2 = Object.keys(valueWrapper).filter((k) => !k.startsWith("_") && !k.startsWith("__"));
416
- for (const key of valueChildKeys2) {
417
- const child = valueWrapper[key];
418
- const isInternal = typeof key === "string" && (key.startsWith("_") || key.startsWith("__"));
419
-
420
- const keyExists = !isInternal && Object.prototype.hasOwnProperty.call(existingWrapper, key);
421
-
422
- if (!keyExists) {
423
- Object.defineProperty(existingWrapper, key, {
424
- value: child,
425
- writable: false,
426
- enumerable: true,
427
- configurable: true
428
- });
429
- } else if (isMergeReplace) {
430
- const descriptor = Object.getOwnPropertyDescriptor(existingWrapper, key);
431
-
432
-
433
-
434
-
435
- if (descriptor?.configurable) {
436
- delete existingWrapper[key];
437
- }
438
- Object.defineProperty(existingWrapper, key, {
439
- value: child,
440
- writable: false,
441
- enumerable: true,
442
- configurable: true
443
- });
444
- } else {
445
-
446
-
447
-
448
- const existingChild = existingWrapper[key];
449
- const existingChildWrapper = resolveWrapper(existingChild);
450
- const newChildWrapper = resolveWrapper(child);
451
-
452
-
453
- if (existingChildWrapper && newChildWrapper) {
454
-
455
- const newChildChildCount = Object.keys(newChildWrapper).filter((k) => !k.startsWith("_") && !k.startsWith("__")).length;
456
- if (newChildWrapper.____slothletInternal.impl && newChildChildCount === 0) {
457
- newChildWrapper.___adoptImplChildren();
458
- }
459
- const newChildKeys = Object.keys(newChildWrapper).filter((k) => !k.startsWith("_") && !k.startsWith("__"));
460
- const ____existingChildKeys = Object.keys(existingChildWrapper).filter((k) => !k.startsWith("_") && !k.startsWith("__"));
461
- for (const childKey of newChildKeys) {
462
- const childKeyExists = Object.prototype.hasOwnProperty.call(existingChildWrapper, childKey);
463
-
464
-
465
- if (!childKeyExists) {
466
- Object.defineProperty(existingChildWrapper, childKey, {
467
- value: newChildWrapper[childKey],
468
- writable: false,
469
- enumerable: true,
470
- configurable: true
471
- });
472
- }
473
- }
474
- }
475
- }
476
- }
477
-
478
- if (
479
- valueWrapper.____slothletInternal.mode === "lazy" &&
480
- !valueWrapper.____slothletInternal.state.materialized &&
481
- valueWrapper.____slothletInternal.materializeFunc
482
- ) {
483
-
484
-
485
- return false;
486
- }
487
-
488
- return true;
489
- } else if (existingIsWrapper && !valueIsWrapper) {
490
-
491
- const existingWrapper = resolveWrapper(existing);
492
- const existingImpl = existingWrapper.__impl;
493
-
494
-
495
- const mergedImpl = { ...(existingImpl || {}), ...value };
496
- existingWrapper.___setImpl(mergedImpl);
497
- return true;
498
- } else if (!existingIsWrapper && valueIsWrapper) {
499
-
500
-
501
- } else {
502
-
503
-
504
-
505
- if (typeof existing === "object" && existing !== null && typeof value === "object" && value !== null) {
506
- Object.assign(existing, value);
507
- return true;
508
- }
509
- }
510
-
511
- }
512
-
513
-
514
- }
515
-
516
-
517
- if (existing !== undefined && !allowOverwrite && !mutateExisting && !useCollisionDetection) {
518
- return false;
519
- }
520
-
521
-
522
- targetApi[key] = value;
523
- return true;
524
- }
525
-
526
-
527
- async mergeApiObjects(targetApi, sourceApi, options = {}) {
528
- const config = options.config;
529
- if (config?.debug?.api) {
530
- this.slothlet.debug("api", {
531
- key: "DEBUG_MODE_MERGE_API_OBJECTS_ENTRY",
532
- targetApiType: typeof targetApi,
533
- sourceApiType: typeof sourceApi
534
- });
535
- this.slothlet.debug("api", {
536
- key: "DEBUG_MODE_MERGE_API_OBJECTS_SOURCE_KEYS",
537
- sourceApiKeys: sourceApi ? Object.keys(sourceApi) : []
538
- });
539
- }
540
-
541
-
542
- if (!sourceApi || (typeof sourceApi !== "object" && typeof sourceApi !== "function")) {
543
- if (config?.debug?.api) {
544
- this.slothlet.debug("api", {
545
- key: "DEBUG_MODE_MERGE_API_OBJECTS_EXIT_INVALID_SOURCE"
546
- });
547
- }
548
- return;
549
- }
550
-
551
- const { removeMissing = false, moduleID = null, ...assignOptions } = options;
552
-
553
-
554
- const sourceKeys = new Set(Object.keys(sourceApi));
555
- for (const key of sourceKeys) {
556
- const sourceValue = sourceApi[key];
557
- const targetValue = targetApi[key];
558
-
559
- if (config?.debug?.api) {
560
- this.slothlet.debug("api", {
561
- key: "DEBUG_MODE_MERGE_API_OBJECTS_PROCESSING_KEY",
562
- propKey: key,
563
- targetValueType: typeof targetValue,
564
- sourceValueType: typeof sourceValue
565
- });
566
- }
567
-
568
-
569
- if (
570
- targetValue &&
571
- typeof targetValue === "object" &&
572
- !this.isWrapperProxy(targetValue) &&
573
- sourceValue &&
574
- typeof sourceValue === "object" &&
575
- !this.isWrapperProxy(sourceValue)
576
- ) {
577
- if (config?.debug?.api) {
578
- this.slothlet.debug("api", {
579
- key: "DEBUG_MODE_MERGE_API_OBJECTS_RECURSING",
580
- propKey: key
581
- });
582
- }
583
- await this.mergeApiObjects(targetValue, sourceValue, options);
584
- } else {
585
-
586
- if (config?.debug?.api) {
587
- this.slothlet.debug("api", {
588
- key: "DEBUG_MODE_MERGE_API_OBJECTS_CALLING_ASSIGN",
589
- propKey: key
590
- });
591
- }
592
- this.assignToApiPath(targetApi, key, sourceValue, { ...assignOptions, moduleID });
593
- }
594
- }
595
-
596
-
597
- if (removeMissing) {
598
- for (const key of Object.keys(targetApi)) {
599
- if (!sourceKeys.has(key)) {
600
- delete targetApi[key];
601
- }
602
- }
603
- }
604
- }
605
- }
17
+ import{ComponentBase}from"@cldmv/slothlet/factories/component-base";import{resolveWrapper}from"@cldmv/slothlet/handlers/unified-wrapper";class ApiAssignment extends ComponentBase{static slothletProperty="apiAssignment";constructor(slothlet){super(slothlet)}isWrapperProxy(value){return!!(value&&resolveWrapper(value))}assignToApiPath(targetApi,key,value,options={}){const valueIsWrapper=this.isWrapperProxy(value);const valueId=valueIsWrapper?resolveWrapper(value)?.____slothletInternal?.id??"no-id":"not-wrapper";this.slothlet.debug("api",{key:"DEBUG_MODE_ASSIGN_TO_API",propKey:key,valueId,typeOf:typeof value});const{allowOverwrite=false,mutateExisting=false,useCollisionDetection=false,config=null,collisionContext="initial",syncWrapper=null,collisionMode="merge",moduleID=null}=options;const existing=targetApi[key];if(existing!==void 0&&this.isWrapperProxy(existing)&&this.isWrapperProxy(value)){if(mutateExisting&&syncWrapper){syncWrapper(existing,value,config,collisionMode,moduleID);return true}}this.slothlet.debug("api",{key:"DEBUG_MODE_COLLISION_CHECK",propKey:key,useCollisionDetection,hasConfig:!!config,hasExisting:existing!==void 0,existingType:typeof existing});if(useCollisionDetection&&config&&existing!==void 0){this.slothlet.debug("api",{key:"DEBUG_MODE_COLLISION_DETECT",propKey:key,context:collisionContext,existingType:typeof existing,valueType:typeof value});const collisionMode2=config.collision?.[collisionContext]||"merge";if(collisionMode2==="error"){const SlothletError=this.slothlet?.SlothletError||Error;throw new SlothletError("COLLISION_ERROR",{key:String(key),collisionMode:collisionMode2,collisionContext})}if(collisionMode2==="skip"){return false}let effectiveMode=collisionMode2;if(collisionMode2==="warn"){new this.slothlet.SlothletWarning("WARNING_COLLISION_FILE_FOLDER_MERGE",{key:String(key)});effectiveMode="merge"}const existingIsWrapper=this.isWrapperProxy(existing);const valueIsWrapper2=this.isWrapperProxy(value);this.slothlet.debug("api",{key:"DEBUG_MODE_COLLISION_WRAPPER_DETECTION",propKey:key,existingIsWrapper,valueIsWrapper:valueIsWrapper2,hasExistingWrapper:resolveWrapper(existing)?"yes":"no",hasValueWrapper:resolveWrapper(value)?"yes":"no"});if(existingIsWrapper&&valueIsWrapper2){const existingWrapper=resolveWrapper(existing);const valueWrapper=resolveWrapper(value);const existingIsLazyUnmaterialized=existingWrapper.____slothletInternal.mode==="lazy"&&!existingWrapper.____slothletInternal.state.materialized;const valueIsLazyUnmaterialized=valueWrapper.____slothletInternal.mode==="lazy"&&!valueWrapper.____slothletInternal.state.materialized;this.slothlet.debug("api",{key:"DEBUG_MODE_COLLISION_LAZY_DETECTION",propKey:key,effectiveMode,existingLazy:existingIsLazyUnmaterialized,valueLazy:valueIsLazyUnmaterialized});if(existingIsLazyUnmaterialized){this.slothlet.debug("api",{key:"DEBUG_MODE_COLLISION_SET_MODE_EXISTING_WRAPPER",effectiveMode,apiPath:existingWrapper.____slothletInternal.apiPath});existingWrapper.____slothletInternal.state.collisionMode=effectiveMode;this.slothlet.debug("api",{key:"DEBUG_MODE_COLLISION_VERIFIED_EXISTING_WRAPPER_MODE",collisionMode:existingWrapper.____slothletInternal.state.collisionMode})}if(valueIsLazyUnmaterialized){this.slothlet.debug("api",{key:"DEBUG_MODE_COLLISION_SET_MODE_VALUE_WRAPPER",effectiveMode,apiPath:valueWrapper.____slothletInternal.apiPath});valueWrapper.____slothletInternal.state.collisionMode=effectiveMode;this.slothlet.debug("api",{key:"DEBUG_MODE_COLLISION_VERIFIED_VALUE_WRAPPER_MODE",collisionMode:valueWrapper.____slothletInternal.state.collisionMode});if(effectiveMode==="replace"){this.slothlet.debug("api",{key:"DEBUG_MODE_COLLISION_REPLACE_MATERIALIZE",apiPath:valueWrapper.____slothletInternal.apiPath});valueWrapper._materialize()}}}if(effectiveMode==="replace"){if(existingIsWrapper&&valueIsWrapper2){const existingWrapper=resolveWrapper(existing);const valueWrapper=resolveWrapper(value);const existingIsLazyUnmaterialized=existingWrapper.____slothletInternal.mode==="lazy"&&!existingWrapper.____slothletInternal.state.materialized;const valueIsLazyUnmaterialized=valueWrapper.____slothletInternal.mode==="lazy"&&!valueWrapper.____slothletInternal.state.materialized;if(valueIsLazyUnmaterialized&&!existingIsLazyUnmaterialized){this.slothlet.debug("api",{key:"DEBUG_MODE_COLLISION_REPLACE_NO_COPY"});this.slothlet.debug("api",{key:"DEBUG_MODE_COLLISION_REPLACE_BEFORE",propKey:key,currentWrapperId:resolveWrapper(existing)?.____slothletInternal.id});this.slothlet.debug("api",{key:"DEBUG_MODE_COLLISION_ASSIGN_REPLACING_WITH_LAZY",propKey:key,collisionMode:valueWrapper.____slothletInternal.state.collisionMode});targetApi[key]=value;this.slothlet.debug("api",{key:"DEBUG_MODE_COLLISION_REPLACE_AFTER",propKey:key,newWrapperId:resolveWrapper(targetApi[key])?.____slothletInternal.id});this.slothlet.debug("api",{key:"DEBUG_MODE_COLLISION_REPLACE_VERIFY",expectedId:valueWrapper.____slothletInternal.id,actualId:resolveWrapper(targetApi[key])?.____slothletInternal.id});return true}}targetApi[key]=value;return true}if(effectiveMode==="merge"||effectiveMode==="merge-replace"){const isMergeReplace=effectiveMode==="merge-replace";if(existingIsWrapper&&valueIsWrapper2){const existingWrapper=resolveWrapper(existing);const valueWrapper=resolveWrapper(value);const existingIsLazyUnmaterialized=existingWrapper.____slothletInternal.mode==="lazy"&&!existingWrapper.____slothletInternal.state.materialized;const valueIsLazyUnmaterialized=valueWrapper.____slothletInternal.mode==="lazy"&&!valueWrapper.____slothletInternal.state.materialized;if(existingIsLazyUnmaterialized&&!valueIsLazyUnmaterialized){const valueMetadata=this.slothlet.handlers?.metadata?.getMetadata(value);const valueFilePath=valueMetadata?.filePath;if(!existingWrapper.____slothletInternal.childFilePathsPreMaterialize){existingWrapper.____slothletInternal.childFilePathsPreMaterialize={}}const valueChildKeys=Object.keys(valueWrapper).filter(k=>!k.startsWith("_")&&!k.startsWith("__"));for(const key2 of valueChildKeys){Object.defineProperty(existingWrapper,key2,{configurable:true});if(valueFilePath){existingWrapper.____slothletInternal.childFilePathsPreMaterialize[key2]=valueFilePath}}return true}else if(valueIsLazyUnmaterialized&&!existingIsLazyUnmaterialized){if(!isMergeReplace){const existingMetadata=this.slothlet.handlers?.metadata?.getMetadata(existing);const existingFilePath=existingMetadata?.filePath;if(!valueWrapper.____slothletInternal.childFilePathsPreMaterialize){valueWrapper.____slothletInternal.childFilePathsPreMaterialize={}}const existingChildKeys=Object.keys(existingWrapper).filter(k=>!k.startsWith("_")&&!k.startsWith("__"));this.slothlet.debug("api",{key:"DEBUG_MODE_COLLISION_COPY_CHILD_KEYS",existingChildKeys:existingChildKeys.join(","),fromApiPath:existingWrapper.____slothletInternal.apiPath,toApiPath:valueWrapper.____slothletInternal.apiPath,valueWrapperId:valueWrapper.____slothletInternal.id||"no-id"});if(!valueWrapper.____slothletInternal.collisionMergedKeys){valueWrapper.____slothletInternal.collisionMergedKeys=new Set}for(const key2 of existingChildKeys){const child=existingWrapper[key2];this.slothlet.debug("api",{key:"DEBUG_MODE_COLLISION_COPY_INDIVIDUAL_KEY",propKey:key2,childName:child?.name,typeOf:typeof child,valueWrapperId:valueWrapper.____slothletInternal.id||"no-id"});Object.defineProperty(valueWrapper,key2,{value:child,writable:false,enumerable:true,configurable:true});valueWrapper.____slothletInternal.collisionMergedKeys.add(key2);if(existingFilePath){valueWrapper.____slothletInternal.childFilePathsPreMaterialize[key2]=existingFilePath}}this.slothlet.debug("api",{key:"DEBUG_MODE_COLLISION_TRIGGER_EARLY_MAT",apiPath:valueWrapper.____slothletInternal.apiPath});valueWrapper.____slothletInternal.needsImmediateChildAdoption=true;if(valueWrapper.____slothletInternal.materializeFunc&&!valueWrapper.____slothletInternal.state?.materialized&&!valueWrapper.____slothletInternal.state?.inFlight){valueWrapper._materialize().catch(err=>{new this.slothlet.SlothletWarning("WARNING_COLLISION_TRIGGER_MATERIALIZE_ERROR",{apiPath:valueWrapper.____slothletInternal.apiPath},err)})}}else{valueWrapper._mergeAfterMaterialize={existingWrapper,isMergeReplace:true}}this.slothlet.debug("api",{key:"DEBUG_MODE_COLLISION_ASSIGN_REPLACING_WITH_LAZY",propKey:key,collisionMode:valueWrapper.____slothletInternal.state.collisionMode});targetApi[key]=value;return true}const existingChildCount=Object.keys(existingWrapper).filter(k=>!k.startsWith("_")&&!k.startsWith("__")).length;const valueChildCount=Object.keys(valueWrapper).filter(k=>!k.startsWith("_")&&!k.startsWith("__")).length;if(existingWrapper.____slothletInternal.impl&&existingChildCount===0){existingWrapper.___adoptImplChildren()}if(valueWrapper.____slothletInternal.impl&&valueChildCount===0){valueWrapper.___adoptImplChildren()}const valueChildKeys2=Object.keys(valueWrapper).filter(k=>!k.startsWith("_")&&!k.startsWith("__"));for(const key2 of valueChildKeys2){const child=valueWrapper[key2];const isInternal=typeof key2==="string"&&(key2.startsWith("_")||key2.startsWith("__"));const keyExists=!isInternal&&Object.prototype.hasOwnProperty.call(existingWrapper,key2);if(!keyExists){Object.defineProperty(existingWrapper,key2,{value:child,writable:false,enumerable:true,configurable:true})}else if(isMergeReplace){const descriptor=Object.getOwnPropertyDescriptor(existingWrapper,key2);if(descriptor?.configurable){delete existingWrapper[key2]}Object.defineProperty(existingWrapper,key2,{value:child,writable:false,enumerable:true,configurable:true})}else{const existingChild=existingWrapper[key2];const existingChildWrapper=resolveWrapper(existingChild);const newChildWrapper=resolveWrapper(child);if(existingChildWrapper&&newChildWrapper){const newChildChildCount=Object.keys(newChildWrapper).filter(k=>!k.startsWith("_")&&!k.startsWith("__")).length;if(newChildWrapper.____slothletInternal.impl&&newChildChildCount===0){newChildWrapper.___adoptImplChildren()}const newChildKeys=Object.keys(newChildWrapper).filter(k=>!k.startsWith("_")&&!k.startsWith("__"));const ____existingChildKeys=Object.keys(existingChildWrapper).filter(k=>!k.startsWith("_")&&!k.startsWith("__"));for(const childKey of newChildKeys){const childKeyExists=Object.prototype.hasOwnProperty.call(existingChildWrapper,childKey);if(!childKeyExists){Object.defineProperty(existingChildWrapper,childKey,{value:newChildWrapper[childKey],writable:false,enumerable:true,configurable:true})}}}}}if(valueWrapper.____slothletInternal.mode==="lazy"&&!valueWrapper.____slothletInternal.state.materialized&&valueWrapper.____slothletInternal.materializeFunc){return false}return true}else if(existingIsWrapper&&!valueIsWrapper2){const existingWrapper=resolveWrapper(existing);const existingImpl=existingWrapper.__impl;const mergedImpl={...existingImpl||{},...value};existingWrapper.___setImpl(mergedImpl);return true}else if(!existingIsWrapper&&valueIsWrapper2){}else{if(typeof existing==="object"&&existing!==null&&typeof value==="object"&&value!==null){Object.assign(existing,value);return true}}}}if(existing!==void 0&&!allowOverwrite&&!mutateExisting&&!useCollisionDetection){return false}targetApi[key]=value;return true}async mergeApiObjects(targetApi,sourceApi,options={}){const config=options.config;if(config?.debug?.api){this.slothlet.debug("api",{key:"DEBUG_MODE_MERGE_API_OBJECTS_ENTRY",targetApiType:typeof targetApi,sourceApiType:typeof sourceApi});this.slothlet.debug("api",{key:"DEBUG_MODE_MERGE_API_OBJECTS_SOURCE_KEYS",sourceApiKeys:sourceApi?Object.keys(sourceApi):[]})}if(!sourceApi||typeof sourceApi!=="object"&&typeof sourceApi!=="function"){if(config?.debug?.api){this.slothlet.debug("api",{key:"DEBUG_MODE_MERGE_API_OBJECTS_EXIT_INVALID_SOURCE"})}return}const{removeMissing=false,moduleID=null,...assignOptions}=options;const sourceKeys=new Set(Object.keys(sourceApi));for(const key of sourceKeys){const sourceValue=sourceApi[key];const targetValue=targetApi[key];if(config?.debug?.api){this.slothlet.debug("api",{key:"DEBUG_MODE_MERGE_API_OBJECTS_PROCESSING_KEY",propKey:key,targetValueType:typeof targetValue,sourceValueType:typeof sourceValue})}if(targetValue&&typeof targetValue==="object"&&!this.isWrapperProxy(targetValue)&&sourceValue&&typeof sourceValue==="object"&&!this.isWrapperProxy(sourceValue)){if(config?.debug?.api){this.slothlet.debug("api",{key:"DEBUG_MODE_MERGE_API_OBJECTS_RECURSING",propKey:key})}await this.mergeApiObjects(targetValue,sourceValue,options)}else{if(config?.debug?.api){this.slothlet.debug("api",{key:"DEBUG_MODE_MERGE_API_OBJECTS_CALLING_ASSIGN",propKey:key})}this.assignToApiPath(targetApi,key,sourceValue,{...assignOptions,moduleID})}}if(removeMissing){for(const key of Object.keys(targetApi)){if(!sourceKeys.has(key)){delete targetApi[key]}}}}}export{ApiAssignment};