@cldmv/slothlet 2.10.0 → 3.0.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 (188) hide show
  1. package/AGENT-USAGE.md +365 -294
  2. package/README.md +556 -233
  3. package/dist/lib/builders/api-assignment.mjs +605 -0
  4. package/dist/lib/builders/api_builder.mjs +1073 -0
  5. package/dist/lib/builders/builder.mjs +94 -0
  6. package/dist/lib/builders/modes-processor.mjs +1816 -0
  7. package/dist/lib/errors.mjs +227 -0
  8. package/dist/lib/factories/component-base.mjs +96 -0
  9. package/dist/lib/factories/context.mjs +38 -0
  10. package/dist/lib/handlers/api-cache-manager.mjs +216 -0
  11. package/dist/lib/handlers/api-manager.mjs +2364 -0
  12. package/dist/lib/handlers/context-async.mjs +184 -0
  13. package/dist/lib/handlers/context-live.mjs +184 -0
  14. package/dist/lib/handlers/hook-manager.mjs +789 -0
  15. package/dist/lib/handlers/lifecycle-token.mjs +44 -0
  16. package/dist/lib/handlers/lifecycle.mjs +131 -0
  17. package/dist/lib/handlers/materialize-manager.mjs +64 -0
  18. package/dist/lib/handlers/metadata.mjs +500 -0
  19. package/dist/lib/handlers/ownership.mjs +338 -0
  20. package/dist/lib/handlers/unified-wrapper.mjs +3031 -0
  21. package/dist/lib/helpers/class-instance-wrapper.mjs +125 -0
  22. package/dist/lib/helpers/config.mjs +343 -0
  23. package/dist/lib/helpers/eventemitter-context.mjs +365 -0
  24. package/dist/lib/helpers/hint-detector.mjs +63 -0
  25. package/dist/lib/helpers/modes-utils.mjs +53 -0
  26. package/dist/lib/helpers/resolve-from-caller.mjs +125 -85
  27. package/dist/lib/helpers/sanitize.mjs +247 -168
  28. package/dist/lib/helpers/utilities.mjs +46 -81
  29. package/dist/lib/i18n/languages/de-de.json +377 -0
  30. package/dist/lib/i18n/languages/en-gb.json +377 -0
  31. package/dist/lib/i18n/languages/en-us.json +377 -0
  32. package/dist/lib/i18n/languages/es-mx.json +377 -0
  33. package/dist/lib/i18n/languages/fr-fr.json +377 -0
  34. package/dist/lib/i18n/languages/hi-in.json +377 -0
  35. package/dist/lib/i18n/languages/ja-jp.json +377 -0
  36. package/dist/lib/i18n/languages/ko-kr.json +377 -0
  37. package/dist/lib/i18n/languages/pt-br.json +377 -0
  38. package/dist/lib/i18n/languages/ru-ru.json +377 -0
  39. package/dist/lib/i18n/languages/zh-cn.json +377 -0
  40. package/dist/lib/i18n/translations.mjs +140 -0
  41. package/dist/lib/modes/eager.mjs +75 -0
  42. package/dist/lib/modes/lazy.mjs +97 -0
  43. package/dist/lib/processors/flatten.mjs +453 -0
  44. package/dist/lib/processors/loader.mjs +355 -0
  45. package/dist/lib/processors/type-generator.mjs +291 -0
  46. package/dist/lib/processors/typescript.mjs +188 -0
  47. package/dist/lib/runtime/runtime-asynclocalstorage.mjs +80 -522
  48. package/dist/lib/runtime/runtime-livebindings.mjs +45 -390
  49. package/dist/lib/runtime/runtime.mjs +39 -159
  50. package/dist/slothlet.mjs +529 -700
  51. package/docs/API-RULES.md +497 -617
  52. package/index.cjs +4 -4
  53. package/index.mjs +82 -45
  54. package/package.json +139 -26
  55. package/types/dist/lib/builders/api-assignment.d.mts +97 -0
  56. package/types/dist/lib/builders/api-assignment.d.mts.map +1 -0
  57. package/types/dist/lib/builders/api_builder.d.mts +96 -0
  58. package/types/dist/lib/builders/api_builder.d.mts.map +1 -0
  59. package/types/dist/lib/builders/builder.d.mts +60 -0
  60. package/types/dist/lib/builders/builder.d.mts.map +1 -0
  61. package/types/dist/lib/builders/modes-processor.d.mts +32 -0
  62. package/types/dist/lib/builders/modes-processor.d.mts.map +1 -0
  63. package/types/dist/lib/errors.d.mts +118 -0
  64. package/types/dist/lib/errors.d.mts.map +1 -0
  65. package/types/dist/lib/factories/component-base.d.mts +182 -0
  66. package/types/dist/lib/factories/component-base.d.mts.map +1 -0
  67. package/types/dist/lib/factories/context.d.mts +26 -0
  68. package/types/dist/lib/factories/context.d.mts.map +1 -0
  69. package/types/dist/lib/handlers/api-cache-manager.d.mts +208 -0
  70. package/types/dist/lib/handlers/api-cache-manager.d.mts.map +1 -0
  71. package/types/dist/lib/handlers/api-manager.d.mts +392 -0
  72. package/types/dist/lib/handlers/api-manager.d.mts.map +1 -0
  73. package/types/dist/lib/handlers/context-async.d.mts +66 -0
  74. package/types/dist/lib/handlers/context-async.d.mts.map +1 -0
  75. package/types/dist/lib/handlers/context-live.d.mts +65 -0
  76. package/types/dist/lib/handlers/context-live.d.mts.map +1 -0
  77. package/types/dist/lib/handlers/hook-manager.d.mts +199 -0
  78. package/types/dist/lib/handlers/hook-manager.d.mts.map +1 -0
  79. package/types/dist/lib/handlers/lifecycle-token.d.mts +49 -0
  80. package/types/dist/lib/handlers/lifecycle-token.d.mts.map +1 -0
  81. package/types/dist/lib/handlers/lifecycle.d.mts +90 -0
  82. package/types/dist/lib/handlers/lifecycle.d.mts.map +1 -0
  83. package/types/dist/lib/handlers/materialize-manager.d.mts +75 -0
  84. package/types/dist/lib/handlers/materialize-manager.d.mts.map +1 -0
  85. package/types/dist/lib/handlers/metadata.d.mts +215 -0
  86. package/types/dist/lib/handlers/metadata.d.mts.map +1 -0
  87. package/types/dist/lib/handlers/ownership.d.mts +170 -0
  88. package/types/dist/lib/handlers/ownership.d.mts.map +1 -0
  89. package/types/dist/lib/handlers/unified-wrapper.d.mts +250 -0
  90. package/types/dist/lib/handlers/unified-wrapper.d.mts.map +1 -0
  91. package/types/dist/lib/helpers/class-instance-wrapper.d.mts +54 -0
  92. package/types/dist/lib/helpers/class-instance-wrapper.d.mts.map +1 -0
  93. package/types/dist/lib/helpers/config.d.mts +96 -0
  94. package/types/dist/lib/helpers/config.d.mts.map +1 -0
  95. package/types/dist/lib/helpers/eventemitter-context.d.mts +31 -0
  96. package/types/dist/lib/helpers/eventemitter-context.d.mts.map +1 -0
  97. package/types/dist/lib/helpers/hint-detector.d.mts +20 -0
  98. package/types/dist/lib/helpers/hint-detector.d.mts.map +1 -0
  99. package/types/dist/lib/helpers/modes-utils.d.mts +35 -0
  100. package/types/dist/lib/helpers/modes-utils.d.mts.map +1 -0
  101. package/types/dist/lib/helpers/resolve-from-caller.d.mts +29 -145
  102. package/types/dist/lib/helpers/resolve-from-caller.d.mts.map +1 -1
  103. package/types/dist/lib/helpers/sanitize.d.mts +95 -94
  104. package/types/dist/lib/helpers/sanitize.d.mts.map +1 -1
  105. package/types/dist/lib/helpers/utilities.d.mts +53 -116
  106. package/types/dist/lib/helpers/utilities.d.mts.map +1 -1
  107. package/types/dist/lib/i18n/translations.d.mts +39 -0
  108. package/types/dist/lib/i18n/translations.d.mts.map +1 -0
  109. package/types/dist/lib/modes/eager.d.mts +36 -0
  110. package/types/dist/lib/modes/eager.d.mts.map +1 -0
  111. package/types/dist/lib/modes/lazy.d.mts +49 -0
  112. package/types/dist/lib/modes/lazy.d.mts.map +1 -0
  113. package/types/dist/lib/processors/flatten.d.mts +114 -0
  114. package/types/dist/lib/processors/flatten.d.mts.map +1 -0
  115. package/types/dist/lib/processors/loader.d.mts +47 -0
  116. package/types/dist/lib/processors/loader.d.mts.map +1 -0
  117. package/types/dist/lib/processors/type-generator.d.mts +19 -0
  118. package/types/dist/lib/processors/type-generator.d.mts.map +1 -0
  119. package/types/dist/lib/processors/typescript.d.mts +55 -0
  120. package/types/dist/lib/processors/typescript.d.mts.map +1 -0
  121. package/types/dist/lib/runtime/runtime-asynclocalstorage.d.mts +47 -42
  122. package/types/dist/lib/runtime/runtime-asynclocalstorage.d.mts.map +1 -1
  123. package/types/dist/lib/runtime/runtime-livebindings.d.mts +34 -65
  124. package/types/dist/lib/runtime/runtime-livebindings.d.mts.map +1 -1
  125. package/types/dist/lib/runtime/runtime.d.mts +39 -9
  126. package/types/dist/lib/runtime/runtime.d.mts.map +1 -1
  127. package/types/dist/slothlet.d.mts +186 -105
  128. package/types/dist/slothlet.d.mts.map +1 -1
  129. package/types/index.d.mts +1 -3
  130. package/dist/lib/engine/README.md +0 -21
  131. package/dist/lib/engine/slothlet_child.mjs +0 -59
  132. package/dist/lib/engine/slothlet_engine.mjs +0 -372
  133. package/dist/lib/engine/slothlet_esm.mjs +0 -230
  134. package/dist/lib/engine/slothlet_helpers.mjs +0 -455
  135. package/dist/lib/engine/slothlet_worker.mjs +0 -149
  136. package/dist/lib/helpers/als-eventemitter.mjs +0 -256
  137. package/dist/lib/helpers/api_builder/add_api.mjs +0 -292
  138. package/dist/lib/helpers/api_builder/analysis.mjs +0 -532
  139. package/dist/lib/helpers/api_builder/construction.mjs +0 -457
  140. package/dist/lib/helpers/api_builder/decisions.mjs +0 -737
  141. package/dist/lib/helpers/api_builder/metadata.mjs +0 -248
  142. package/dist/lib/helpers/api_builder.mjs +0 -41
  143. package/dist/lib/helpers/auto-wrap.mjs +0 -62
  144. package/dist/lib/helpers/hooks.mjs +0 -389
  145. package/dist/lib/helpers/instance-manager.mjs +0 -111
  146. package/dist/lib/helpers/metadata-api.mjs +0 -201
  147. package/dist/lib/helpers/multidefault.mjs +0 -216
  148. package/dist/lib/modes/slothlet_eager.mjs +0 -126
  149. package/dist/lib/modes/slothlet_lazy.mjs +0 -513
  150. package/docs/API-RULES-CONDITIONS.md +0 -508
  151. package/types/dist/lib/engine/slothlet_child.d.mts +0 -2
  152. package/types/dist/lib/engine/slothlet_child.d.mts.map +0 -1
  153. package/types/dist/lib/engine/slothlet_engine.d.mts +0 -31
  154. package/types/dist/lib/engine/slothlet_engine.d.mts.map +0 -1
  155. package/types/dist/lib/engine/slothlet_esm.d.mts +0 -19
  156. package/types/dist/lib/engine/slothlet_esm.d.mts.map +0 -1
  157. package/types/dist/lib/engine/slothlet_helpers.d.mts +0 -25
  158. package/types/dist/lib/engine/slothlet_helpers.d.mts.map +0 -1
  159. package/types/dist/lib/engine/slothlet_worker.d.mts +0 -2
  160. package/types/dist/lib/engine/slothlet_worker.d.mts.map +0 -1
  161. package/types/dist/lib/helpers/als-eventemitter.d.mts +0 -56
  162. package/types/dist/lib/helpers/als-eventemitter.d.mts.map +0 -1
  163. package/types/dist/lib/helpers/api_builder/add_api.d.mts +0 -76
  164. package/types/dist/lib/helpers/api_builder/add_api.d.mts.map +0 -1
  165. package/types/dist/lib/helpers/api_builder/analysis.d.mts +0 -189
  166. package/types/dist/lib/helpers/api_builder/analysis.d.mts.map +0 -1
  167. package/types/dist/lib/helpers/api_builder/construction.d.mts +0 -107
  168. package/types/dist/lib/helpers/api_builder/construction.d.mts.map +0 -1
  169. package/types/dist/lib/helpers/api_builder/decisions.d.mts +0 -213
  170. package/types/dist/lib/helpers/api_builder/decisions.d.mts.map +0 -1
  171. package/types/dist/lib/helpers/api_builder/metadata.d.mts +0 -99
  172. package/types/dist/lib/helpers/api_builder/metadata.d.mts.map +0 -1
  173. package/types/dist/lib/helpers/api_builder.d.mts +0 -6
  174. package/types/dist/lib/helpers/api_builder.d.mts.map +0 -1
  175. package/types/dist/lib/helpers/auto-wrap.d.mts +0 -49
  176. package/types/dist/lib/helpers/auto-wrap.d.mts.map +0 -1
  177. package/types/dist/lib/helpers/hooks.d.mts +0 -342
  178. package/types/dist/lib/helpers/hooks.d.mts.map +0 -1
  179. package/types/dist/lib/helpers/instance-manager.d.mts +0 -41
  180. package/types/dist/lib/helpers/instance-manager.d.mts.map +0 -1
  181. package/types/dist/lib/helpers/metadata-api.d.mts +0 -132
  182. package/types/dist/lib/helpers/metadata-api.d.mts.map +0 -1
  183. package/types/dist/lib/helpers/multidefault.d.mts +0 -90
  184. package/types/dist/lib/helpers/multidefault.d.mts.map +0 -1
  185. package/types/dist/lib/modes/slothlet_eager.d.mts +0 -65
  186. package/types/dist/lib/modes/slothlet_eager.d.mts.map +0 -1
  187. package/types/dist/lib/modes/slothlet_lazy.d.mts +0 -31
  188. package/types/dist/lib/modes/slothlet_lazy.d.mts.map +0 -1
@@ -0,0 +1,1073 @@
1
+ /*
2
+ Copyright 2026 CLDMV/Shinrai
3
+
4
+ Licensed under the Apache License, Version 2.0 (the "License");
5
+ you may not use this file except in compliance with the License.
6
+ You may obtain a copy of the License at
7
+
8
+ http://www.apache.org/licenses/LICENSE-2.0
9
+
10
+ Unless required by applicable law or agreed to in writing, software
11
+ distributed under the License is distributed on an "AS IS" BASIS,
12
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ See the License for the specific language governing permissions and
14
+ limitations under the License.
15
+ */
16
+
17
+
18
+
19
+
20
+ import { ComponentBase } from "@cldmv/slothlet/factories/component-base";
21
+ import { TYPE_STATES } from "@cldmv/slothlet/handlers/unified-wrapper";
22
+ import { getLanguage, initI18n, setLanguage, t, translate } from "@cldmv/slothlet/i18n";
23
+
24
+
25
+
26
+
27
+ function _resolvePathOrModuleId(slothlet, pathOrModuleId) {
28
+ const history = slothlet.handlers?.apiManager?.state?.addHistory;
29
+
30
+
31
+
32
+ if (history) {
33
+ const match = history.findLast((entry) => entry.moduleID === pathOrModuleId);
34
+ if (match) return match.apiPath;
35
+ }
36
+ return pathOrModuleId;
37
+ }
38
+
39
+
40
+ export class ApiBuilder extends ComponentBase {
41
+ static slothletProperty = "apiBuilder";
42
+
43
+
44
+ constructor(slothlet) {
45
+ super(slothlet);
46
+ }
47
+
48
+
49
+ async buildFinalAPI(userApi) {
50
+ this.slothlet.debug("api", {
51
+ key: "DEBUG_MODE_BUILD_FINAL_API_CALLED",
52
+ diagnostics: this.____config.diagnostics,
53
+ userApiKeys: Object.keys(userApi)
54
+ });
55
+
56
+
57
+
58
+
59
+
60
+
61
+
62
+
63
+
64
+
65
+
66
+
67
+
68
+
69
+
70
+
71
+
72
+ if (this.slothlet._ownBuiltins) {
73
+ for (const [key, ref] of Object.entries(this.slothlet._ownBuiltins)) {
74
+ if (ref && Object.prototype.hasOwnProperty.call(userApi, key) && userApi[key] === ref) {
75
+ try {
76
+ delete userApi[key];
77
+ } catch (_) {
78
+
79
+ }
80
+ }
81
+ }
82
+ }
83
+
84
+
85
+
86
+
87
+
88
+ this.slothlet.userHooks = {
89
+ shutdown: typeof userApi.shutdown === "function" ? userApi.shutdown : null,
90
+ destroy: typeof userApi.destroy === "function" ? userApi.destroy : null
91
+ };
92
+
93
+
94
+
95
+ if (userApi.slothlet) {
96
+ new this.SlothletWarning("WARNING_RESERVED_PROPERTY_CONFLICT", { properties: "slothlet" });
97
+ }
98
+
99
+
100
+ const slothletNamespace = await this.createSlothletNamespace(userApi);
101
+
102
+ this.slothlet.debug("api", {
103
+ key: "DEBUG_MODE_SLOTHLET_NAMESPACE_CREATED",
104
+ namespaceKeys: Object.keys(slothletNamespace),
105
+ hasDiag: !!slothletNamespace.diag
106
+ });
107
+
108
+
109
+ const shutdownFn = this.createShutdownFunction();
110
+
111
+
112
+ this.attachBuiltins(userApi, {
113
+ slothlet: slothletNamespace,
114
+ shutdown: shutdownFn,
115
+ destroy: null
116
+ });
117
+
118
+ this.slothlet.debug("api", {
119
+ key: "DEBUG_MODE_BUILT_INS_ATTACHED",
120
+ userApiKeys: Object.keys(userApi),
121
+ hasSlothlet: !!userApi.slothlet,
122
+ hasDiag: !!userApi.slothlet?.diag
123
+ });
124
+
125
+
126
+ const destroyWithApi = this.createDestroyFunction(userApi);
127
+ Object.defineProperty(userApi, "destroy", {
128
+ value: destroyWithApi,
129
+ enumerable: true,
130
+ writable: false,
131
+ configurable: true
132
+ });
133
+
134
+
135
+
136
+ this.slothlet._ownBuiltins = {
137
+ shutdown: shutdownFn,
138
+ slothlet: slothletNamespace,
139
+ destroy: destroyWithApi
140
+ };
141
+
142
+ return userApi;
143
+ }
144
+
145
+
146
+ async createSlothletNamespace(userApi) {
147
+ const slothlet = this.slothlet;
148
+ const config = this.____config;
149
+
150
+
151
+ let version = "unknown";
152
+ try {
153
+ const pkgPath = new URL("../../../package.json", import.meta.url);
154
+ const { readFile } = await import("node:fs/promises");
155
+ const pkgContent = await readFile(pkgPath, "utf-8");
156
+ const pkg = JSON.parse(pkgContent);
157
+
158
+
159
+ version = pkg.version || "unknown";
160
+
161
+
162
+
163
+ } catch {
164
+
165
+ }
166
+
167
+ const namespace = {
168
+
169
+ i18n: {
170
+ setLanguage,
171
+ getLanguage,
172
+ translate,
173
+ t,
174
+ initI18n
175
+ },
176
+
177
+
178
+ version,
179
+
180
+
181
+ instanceID: slothlet.instanceID,
182
+
183
+
184
+ types: TYPE_STATES,
185
+
186
+
187
+ api: {
188
+
189
+ add: async function slothlet_api_add(apiPath, folderPath, options = {}) {
190
+
191
+ if (!config.api?.mutations?.add) {
192
+ throw new slothlet.SlothletError("INVALID_CONFIG_MUTATIONS_DISABLED", {
193
+ operation: "api.add",
194
+ validationError: true
195
+ });
196
+ }
197
+
198
+
199
+
200
+
201
+
202
+ const {
203
+ recordHistory: ____recordHistory,
204
+ collisionMode: ____collisionMode,
205
+ mutateExisting: ____mutateExisting,
206
+ ...filteredOptions
207
+ } = options;
208
+ return slothlet.handlers.apiManager.addApiComponent({
209
+ apiPath,
210
+ folderPath,
211
+ options: filteredOptions
212
+ });
213
+ },
214
+
215
+
216
+ remove: async function slothlet_api_remove(pathOrModuleId) {
217
+
218
+ if (!config.api?.mutations?.remove) {
219
+ throw new slothlet.SlothletError("INVALID_CONFIG_MUTATIONS_DISABLED", {
220
+ operation: "api.remove",
221
+ validationError: true
222
+ });
223
+ }
224
+ if (typeof pathOrModuleId !== "string") {
225
+ throw new slothlet.SlothletError("INVALID_ARGUMENT", {
226
+ argument: "pathOrModuleId",
227
+ expected: "string",
228
+ received: typeof pathOrModuleId,
229
+ validationError: true
230
+ });
231
+ }
232
+ return slothlet.handlers.apiManager.removeApiComponent(pathOrModuleId);
233
+ },
234
+
235
+
236
+ reload: async function slothlet_api_reload(pathOrModuleId, options) {
237
+
238
+ if (!config.api?.mutations?.reload) {
239
+ throw new slothlet.SlothletError("INVALID_CONFIG_MUTATIONS_DISABLED", {
240
+ operation: "api.reload",
241
+ validationError: true
242
+ });
243
+ }
244
+
245
+
246
+ if (pathOrModuleId == null || pathOrModuleId === "" || pathOrModuleId === ".") {
247
+ return slothlet.handlers.apiManager.reloadApiComponent({ apiPath: ".", options });
248
+ }
249
+
250
+ if (typeof pathOrModuleId !== "string") {
251
+ throw new slothlet.SlothletError("INVALID_ARGUMENT", {
252
+ argument: "pathOrModuleId",
253
+ expected: "string, null, undefined, or '.'",
254
+ received: typeof pathOrModuleId,
255
+ validationError: true
256
+ });
257
+ }
258
+
259
+
260
+ const isModuleId = slothlet.handlers.apiManager.state.addHistory.some((entry) => entry.moduleID === pathOrModuleId);
261
+
262
+ if (isModuleId) {
263
+ return slothlet.handlers.apiManager.reloadApiComponent({ moduleID: pathOrModuleId, options });
264
+ }
265
+
266
+
267
+ const normalizedPath = slothlet.handlers.apiManager.normalizeApiPath(pathOrModuleId).apiPath;
268
+ const pathParts = normalizedPath.split(".");
269
+ let current = slothlet.api;
270
+ for (const part of pathParts) {
271
+ if (!current || (typeof current !== "object" && typeof current !== "function")) {
272
+ throw new slothlet.SlothletError("INVALID_API_PATH", {
273
+ apiPath: pathOrModuleId,
274
+ validationError: true
275
+ });
276
+ }
277
+ current = current[part];
278
+ }
279
+
280
+ if (current === undefined) {
281
+ throw new slothlet.SlothletError("INVALID_API_PATH", {
282
+ apiPath: pathOrModuleId,
283
+ validationError: true
284
+ });
285
+ }
286
+
287
+
288
+ return slothlet.handlers.apiManager.reloadApiComponent({ apiPath: normalizedPath, options });
289
+ }
290
+ },
291
+
292
+
293
+ sanitize: function slothlet_sanitize(str) {
294
+ if (typeof str !== "string") {
295
+ throw new slothlet.SlothletError("INVALID_ARGUMENT", {
296
+ argument: "str",
297
+ expected: "string",
298
+ received: typeof str,
299
+ validationError: true
300
+ });
301
+ }
302
+ return slothlet.helpers.sanitize.sanitizePropertyName(str, slothlet.config.sanitize || {});
303
+ },
304
+
305
+
306
+ context: {
307
+
308
+ get: (key) => {
309
+
310
+
311
+
312
+
313
+ if (slothlet.contextManager.constructor.name === "LiveContextManager") {
314
+ const currentID = slothlet.contextManager.currentInstanceID;
315
+
316
+
317
+
318
+
319
+ if (currentID) {
320
+ const activeStore = slothlet.contextManager.instances.get(currentID);
321
+ const isOurInstance =
322
+ currentID === slothlet.instanceID ||
323
+ currentID?.startsWith(slothlet.instanceID + "__run_") ||
324
+ activeStore?.parentInstanceID === slothlet.instanceID;
325
+
326
+ if (isOurInstance && activeStore) {
327
+ return key ? activeStore.context[key] : { ...activeStore.context };
328
+ }
329
+ }
330
+
331
+
332
+ const store = slothlet.contextManager.instances.get(slothlet.instanceID);
333
+
334
+
335
+
336
+ if (!store) {
337
+ const baseContext = slothlet.context || {};
338
+ return key ? baseContext[key] : { ...baseContext };
339
+ }
340
+
341
+
342
+ return key ? store.context[key] : { ...store.context };
343
+ }
344
+
345
+
346
+ if (slothlet.contextManager.constructor.name === "AsyncContextManager") {
347
+ let currentStore = slothlet.contextManager.tryGetContext();
348
+
349
+
350
+
351
+ if (!currentStore) {
352
+ const baseStore = slothlet.contextManager.instances.get(slothlet.instanceID);
353
+
354
+
355
+ const baseContext = baseStore?.context || {};
356
+ return key ? baseContext[key] : { ...baseContext };
357
+
358
+ }
359
+
360
+
361
+ const isOurInstance =
362
+ currentStore.instanceID === slothlet.instanceID ||
363
+ currentStore.parentInstanceID === slothlet.instanceID ||
364
+ currentStore.instanceID.startsWith(slothlet.instanceID + "__run_");
365
+
366
+ if (isOurInstance) {
367
+
368
+ return key ? currentStore.context[key] : { ...currentStore.context };
369
+ }
370
+
371
+
372
+ const baseStore = slothlet.contextManager.instances.get(slothlet.instanceID);
373
+
374
+
375
+ const baseContext = baseStore?.context || {};
376
+ return key ? baseContext[key] : { ...baseContext };
377
+
378
+ }
379
+
380
+
381
+
382
+
383
+
384
+ const baseContext = slothlet.context || {};
385
+ return key ? baseContext[key] : { ...baseContext };
386
+
387
+ },
388
+
389
+
390
+ diagnostics: () => {
391
+
392
+
393
+
394
+
395
+ if (!slothlet.config?.diagnostics) return undefined;
396
+ const managerType = slothlet.contextManager.constructor.name;
397
+ const result = {
398
+ instanceID: slothlet.instanceID,
399
+ managerType,
400
+ instancesMapSize: slothlet.contextManager.instances.size,
401
+ instancesMapKeys: Array.from(slothlet.contextManager.instances.keys()),
402
+ baseContext: slothlet.context
403
+ };
404
+
405
+
406
+ const store = slothlet.contextManager.instances.get(slothlet.instanceID);
407
+
408
+
409
+
410
+ result.storeFromInstancesMap = store
411
+ ? {
412
+ instanceID: store.instanceID,
413
+ context: store.context,
414
+ createdAt: store.createdAt
415
+ }
416
+ : null;
417
+
418
+
419
+ if (managerType === "AsyncContextManager") {
420
+ try {
421
+ const currentCtx = slothlet.contextManager.tryGetContext();
422
+ result.currentALSContext = currentCtx
423
+ ? {
424
+ instanceID: currentCtx.instanceID,
425
+ context: currentCtx.context,
426
+ hasParent: !!currentCtx.parentContext,
427
+ parentInstanceID: currentCtx.parentInstanceID
428
+ }
429
+ : null;
430
+
431
+
432
+
433
+ } catch (____error) {
434
+ result.currentALSContext = null;
435
+ }
436
+
437
+ }
438
+
439
+
440
+ if (managerType === "LiveContextManager") {
441
+ result.currentInstanceID = slothlet.contextManager.currentInstanceID;
442
+ }
443
+
444
+ return result;
445
+ },
446
+
447
+
448
+ run: this.createRunFunction(),
449
+
450
+
451
+ scope: this.createScopeFunction()
452
+ },
453
+
454
+
455
+ hook: {
456
+
457
+ on: function slothlet_hook_on(typePattern, handler, options = {}) {
458
+ if (!slothlet.handlers?.hookManager) {
459
+ throw new slothlet.SlothletError("HOOKS_NOT_INITIALIZED", { validationError: true });
460
+ }
461
+ return slothlet.handlers.hookManager.on(typePattern, handler, options);
462
+ },
463
+
464
+
465
+ remove: function slothlet_hook_remove(filter = {}) {
466
+ if (!slothlet.handlers?.hookManager) {
467
+ throw new slothlet.SlothletError("HOOKS_NOT_INITIALIZED", { validationError: true });
468
+ }
469
+ return slothlet.handlers.hookManager.remove(filter);
470
+ },
471
+
472
+
473
+ clear: function slothlet_hook_clear(filter = {}) {
474
+ return this.remove(filter);
475
+ },
476
+
477
+
478
+ off: function slothlet_hook_off(idOrFilter) {
479
+ if (!slothlet.handlers?.hookManager) {
480
+ throw new slothlet.SlothletError("HOOKS_NOT_INITIALIZED", { validationError: true });
481
+ }
482
+
483
+ const filter = typeof idOrFilter === "string" ? { id: idOrFilter } : idOrFilter;
484
+ return slothlet.handlers.hookManager.remove(filter);
485
+ },
486
+
487
+
488
+ enable: function slothlet_hook_enable(filter = {}) {
489
+ if (!slothlet.handlers?.hookManager) {
490
+ throw new slothlet.SlothletError("HOOKS_NOT_INITIALIZED", { validationError: true });
491
+ }
492
+ return slothlet.handlers.hookManager.enable(filter);
493
+ },
494
+
495
+
496
+ disable: function slothlet_hook_disable(filter = {}) {
497
+ if (!slothlet.handlers?.hookManager) {
498
+ throw new slothlet.SlothletError("HOOKS_NOT_INITIALIZED", { validationError: true });
499
+ }
500
+ return slothlet.handlers.hookManager.disable(filter);
501
+ },
502
+
503
+
504
+ list: function slothlet_hook_list(filter = {}) {
505
+ if (!slothlet.handlers?.hookManager) {
506
+ throw new slothlet.SlothletError("HOOKS_NOT_INITIALIZED", { validationError: true });
507
+ }
508
+ return slothlet.handlers.hookManager.list(filter);
509
+ }
510
+ },
511
+
512
+
513
+ metadata: {
514
+
515
+ setGlobal: function slothlet_metadata_setGlobal(key, value) {
516
+
517
+
518
+
519
+
520
+ if (!slothlet.handlers?.metadata) {
521
+ throw new slothlet.SlothletError("METADATA_NOT_AVAILABLE", {
522
+ handlersKeys: slothlet.handlers ? Object.keys(slothlet.handlers).join(", ") : "undefined",
523
+ validationError: true
524
+ });
525
+ }
526
+
527
+ return slothlet.handlers.metadata.setGlobalMetadata(key, value);
528
+ },
529
+
530
+
531
+ set: function slothlet_metadata_set(fn, key, value) {
532
+ if (!slothlet.handlers?.metadata) {
533
+ throw new slothlet.SlothletError("METADATA_NOT_AVAILABLE", {
534
+ handlersKeys: slothlet.handlers
535
+ ? Object.keys(slothlet.handlers).join(", ")
536
+ :
537
+
538
+ "undefined",
539
+ validationError: true
540
+ });
541
+ }
542
+ return slothlet.handlers.metadata.setUserMetadata(fn, key, value);
543
+ },
544
+
545
+
546
+ remove: function slothlet_metadata_remove(fn, key) {
547
+ return slothlet.handlers.metadata.removeUserMetadata(fn, key);
548
+ },
549
+
550
+
551
+ setFor: function slothlet_metadata_setFor(pathOrModuleId, keyOrObj, value) {
552
+ if (!slothlet.handlers?.metadata) {
553
+ throw new slothlet.SlothletError("METADATA_NOT_AVAILABLE", {
554
+ handlersKeys: slothlet.handlers
555
+ ? Object.keys(slothlet.handlers).join(", ")
556
+ :
557
+
558
+ "undefined",
559
+ validationError: true
560
+ });
561
+ }
562
+ const resolvedPath = _resolvePathOrModuleId(slothlet, pathOrModuleId);
563
+ return slothlet.handlers.metadata.setPathMetadata(resolvedPath, keyOrObj, value);
564
+ },
565
+
566
+
567
+ removeFor: function slothlet_metadata_removeFor(pathOrModuleId, key) {
568
+ if (!slothlet.handlers?.metadata) return;
569
+ const resolvedPath = _resolvePathOrModuleId(slothlet, pathOrModuleId);
570
+ return slothlet.handlers.metadata.removePathMetadata(resolvedPath, key);
571
+ }
572
+ },
573
+
574
+
575
+ scope: this.createScopeFunction(),
576
+
577
+
578
+ run: this.createRunFunction(),
579
+
580
+
581
+ reload: async (options = {}) => {
582
+
583
+ if (!config.api?.mutations?.reload) {
584
+ throw new slothlet.SlothletError("INVALID_CONFIG_MUTATIONS_DISABLED", {
585
+ operation: "reload",
586
+ validationError: true
587
+ });
588
+ }
589
+ return slothlet.reload(options);
590
+ },
591
+
592
+
593
+ shutdown: async () => {
594
+ return slothlet.shutdown();
595
+ },
596
+
597
+
598
+ owner: {
599
+
600
+ get: (apiPath) => {
601
+ if (slothlet.handlers?.ownership) {
602
+ return slothlet.handlers.ownership.getPathOwnership(apiPath);
603
+ }
604
+ return null;
605
+ }
606
+ },
607
+
608
+
609
+ materialize: (() => {
610
+ const mgr = slothlet.handlers?.materialize;
611
+
612
+
613
+ if (!mgr) {
614
+ return Object.freeze({
615
+ materialized: false,
616
+ get: () => ({ total: 0, materialized: 0, remaining: 0, percentage: 100 }),
617
+ wait: async () => {}
618
+ });
619
+ }
620
+
621
+ return Object.freeze({
622
+ get materialized() {
623
+ return mgr.materialized;
624
+ },
625
+ get: mgr.get.bind(mgr),
626
+ wait: mgr.wait.bind(mgr)
627
+ });
628
+ })(),
629
+
630
+
631
+ lifecycle: (() => {
632
+ const handler = slothlet.handlers?.lifecycle;
633
+ const noop = () => {};
634
+ if (!handler) return { on: noop, off: noop };
635
+ return {
636
+ on: handler.on.bind(handler),
637
+ off: handler.off.bind(handler)
638
+ };
639
+ })()
640
+ };
641
+
642
+
643
+
644
+ if (!config.hook?.enabled && config.diagnostics !== true) {
645
+ delete namespace.hooks;
646
+ }
647
+
648
+
649
+ if (config.diagnostics === true) {
650
+ namespace.diag = {
651
+
652
+ describe: (showAll = false) => {
653
+ if (showAll) {
654
+
655
+ return { ...userApi };
656
+ }
657
+
658
+ return Reflect.ownKeys(userApi);
659
+ },
660
+
661
+
662
+ reference: slothlet.reference || null,
663
+
664
+
665
+ context: slothlet.context || {},
666
+
667
+
668
+ inspect: () => {
669
+ return slothlet.getDiagnostics();
670
+ },
671
+
672
+
673
+ getAPI: () => {
674
+ return slothlet.getAPI();
675
+ },
676
+
677
+
678
+ getOwnership: () => {
679
+ return slothlet.getOwnership();
680
+ },
681
+
682
+
683
+ owner: {
684
+
685
+ get: (apiPath) => {
686
+ if (slothlet.handlers?.ownership) {
687
+ return slothlet.handlers.ownership.getPathOwnership(apiPath);
688
+ }
689
+ return null;
690
+ }
691
+ },
692
+
693
+
694
+ caches: {
695
+
696
+ get: () => {
697
+ if (slothlet.handlers?.apiCacheManager) {
698
+ return slothlet.handlers.apiCacheManager.getCacheDiagnostics();
699
+ }
700
+ return { totalCaches: 0, caches: [] };
701
+ },
702
+
703
+
704
+ getAllModuleIDs: () => {
705
+ if (slothlet.handlers?.apiCacheManager) {
706
+ return slothlet.handlers.apiCacheManager.getAllModuleIDs();
707
+ }
708
+ return [];
709
+ },
710
+
711
+
712
+ has: (moduleID) => {
713
+ if (slothlet.handlers?.apiCacheManager) {
714
+ return slothlet.handlers.apiCacheManager.has(moduleID);
715
+ }
716
+ return false;
717
+ }
718
+ },
719
+
720
+
721
+ SlothletWarning: slothlet.SlothletWarning,
722
+
723
+
724
+
725
+
726
+ hook: slothlet.handlers?.hookManager
727
+ ? {
728
+
729
+ get enabled() {
730
+ return slothlet.handlers.hookManager.enabled;
731
+ },
732
+
733
+
734
+ compilePattern: (pattern) => {
735
+ return slothlet.handlers.hookManager.getCompilePatternForDiagnostics()(pattern);
736
+ }
737
+ }
738
+ : undefined
739
+
740
+ };
741
+ }
742
+
743
+ return namespace;
744
+ }
745
+
746
+
747
+ createShutdownFunction() {
748
+ const slothlet = this.slothlet;
749
+ const shutdownFunction = {
750
+ shutdown: async () => {
751
+
752
+ if (slothlet.userHooks?.shutdown && typeof slothlet.userHooks.shutdown === "function") {
753
+ await slothlet.userHooks.shutdown();
754
+ }
755
+ return slothlet.shutdown();
756
+ }
757
+ }.shutdown;
758
+ return shutdownFunction;
759
+ }
760
+
761
+
762
+ createRunFunction() {
763
+ const slothlet = this.slothlet;
764
+
765
+ const scopeFunc = this.createScopeFunction();
766
+
767
+ const runFunction = {
768
+ run: async (contextData, callback, ...args) => {
769
+
770
+ if (slothlet.config.scope === false) {
771
+ throw new slothlet.SlothletError("SCOPE_DISABLED", {}, null, { validationError: true });
772
+ }
773
+
774
+
775
+ if (!contextData || typeof contextData !== "object") {
776
+ throw new slothlet.SlothletError("SCOPE_INVALID_CONTEXT", { received: typeof contextData }, null, { validationError: true });
777
+ }
778
+ if (typeof callback !== "function") {
779
+ throw new slothlet.SlothletError("SCOPE_INVALID_CALLBACK", { received: typeof callback }, null, { validationError: true });
780
+ }
781
+
782
+
783
+
784
+ return scopeFunc({
785
+ context: contextData,
786
+ fn: callback,
787
+ args: args,
788
+ merge: slothlet.config.scope?.merge || "shallow",
789
+ isolation: slothlet.config.scope?.isolation || "partial"
790
+ });
791
+ }
792
+ }.run;
793
+ return runFunction;
794
+ }
795
+
796
+
797
+ createScopeFunction() {
798
+ const slothlet = this.slothlet;
799
+ const scopeFunction = {
800
+ scope: async (options) => {
801
+
802
+ if (slothlet.config.scope === false) {
803
+ throw new slothlet.SlothletError("SCOPE_DISABLED", {}, null, { validationError: true });
804
+ }
805
+
806
+
807
+ if (!options || typeof options !== "object") {
808
+ throw new slothlet.SlothletError("SCOPE_INVALID_OPTIONS", { received: typeof options }, null, { validationError: true });
809
+ }
810
+ if (!options.fn || typeof options.fn !== "function") {
811
+ throw new slothlet.SlothletError("SCOPE_INVALID_FN", { received: typeof options?.fn }, null, { validationError: true });
812
+ }
813
+ if (!options.context || typeof options.context !== "object") {
814
+ throw new slothlet.SlothletError("SCOPE_INVALID_CONTEXT_OBJECT", { received: typeof options?.context }, null, {
815
+ validationError: true
816
+ });
817
+ }
818
+
819
+ const { context: contextData, fn, args = [], merge = "shallow", isolation } = options;
820
+
821
+
822
+ if (merge !== "shallow" && merge !== "deep") {
823
+ throw new slothlet.SlothletError("SCOPE_INVALID_MERGE_STRATEGY", { merge }, null, { validationError: true });
824
+ }
825
+
826
+
827
+ const isolationMode = isolation || slothlet.config.scope?.isolation || "partial";
828
+
829
+
830
+ if (isolationMode !== "partial" && isolationMode !== "full") {
831
+ throw new slothlet.SlothletError("SCOPE_INVALID_ISOLATION_MODE", { isolationMode }, null, { validationError: true });
832
+ }
833
+
834
+
835
+ const contextManager = slothlet.contextManager;
836
+ if (!contextManager) {
837
+ throw new slothlet.SlothletError("NO_CONTEXT_MANAGER", { validationError: true });
838
+ }
839
+
840
+ const { utilities } = slothlet.helpers;
841
+
842
+
843
+ if (contextManager.constructor.name === "LiveContextManager") {
844
+
845
+ let currentStore = null;
846
+
847
+
848
+ const currentID = contextManager.currentInstanceID;
849
+ if (currentID) {
850
+ const activeStore = contextManager.instances.get(currentID);
851
+ const isOurContext =
852
+ currentID === slothlet.instanceID ||
853
+ activeStore?.parentInstanceID === slothlet.instanceID ||
854
+ currentID.startsWith(slothlet.instanceID + "__run_");
855
+
856
+ if (isOurContext) {
857
+ currentStore = activeStore;
858
+ }
859
+ }
860
+
861
+
862
+ if (!currentStore) {
863
+ currentStore = contextManager.instances.get(slothlet.instanceID);
864
+ }
865
+
866
+ if (!currentStore) {
867
+ throw new slothlet.SlothletError("CONTEXT_NOT_FOUND", {
868
+ instanceID: slothlet.instanceID,
869
+ availableInstances: [...contextManager.instances.keys()].join(", ") || "none",
870
+ validationError: true
871
+ });
872
+ }
873
+
874
+
875
+
876
+ let mergedContext;
877
+ if (merge === "deep") {
878
+ mergedContext = utilities.deepMerge(currentStore.context, contextData);
879
+
880
+ mergedContext = structuredClone(mergedContext);
881
+ } else {
882
+
883
+ const clonedParent = structuredClone(currentStore.context);
884
+ mergedContext = { ...clonedParent, ...contextData };
885
+ }
886
+
887
+
888
+ const childInstanceID = `${slothlet.instanceID}__run_${Date.now()}_${Math.random().toString(36).slice(2, 9)}`;
889
+
890
+ const childStore = {
891
+ instanceID: childInstanceID,
892
+ context: mergedContext,
893
+ self: isolationMode === "full" ? utilities.deepClone(currentStore.self) : currentStore.self,
894
+ config: currentStore.config,
895
+ createdAt: currentStore.createdAt,
896
+ parentInstanceID: slothlet.instanceID
897
+ };
898
+
899
+
900
+ contextManager.instances.set(childInstanceID, childStore);
901
+ const previousInstanceID = contextManager.currentInstanceID;
902
+
903
+ try {
904
+
905
+ contextManager.currentInstanceID = childInstanceID;
906
+
907
+
908
+ return await fn(...args);
909
+ } finally {
910
+
911
+ contextManager.currentInstanceID = previousInstanceID;
912
+ contextManager.instances.delete(childInstanceID);
913
+ }
914
+ }
915
+
916
+
917
+ if (contextManager.constructor.name === "AsyncContextManager") {
918
+
919
+ let currentStore = null;
920
+
921
+
922
+ const activeStore = contextManager.tryGetContext();
923
+ if (activeStore) {
924
+ const isOurContext =
925
+ activeStore.instanceID === slothlet.instanceID ||
926
+ activeStore.parentInstanceID === slothlet.instanceID ||
927
+ activeStore.instanceID.startsWith(slothlet.instanceID + "__run_");
928
+
929
+ if (isOurContext) {
930
+ currentStore = activeStore;
931
+ }
932
+ }
933
+
934
+
935
+ if (!currentStore) {
936
+ const baseStore = contextManager.instances.get(slothlet.instanceID);
937
+ if (!baseStore) {
938
+ throw new slothlet.SlothletError("CONTEXT_NOT_FOUND", {
939
+ instanceID: slothlet.instanceID,
940
+ availableInstances: [...contextManager.instances.keys()].join(", ") || "none",
941
+ validationError: true
942
+ });
943
+ }
944
+ currentStore = baseStore;
945
+ }
946
+
947
+
948
+
949
+ let mergedContext;
950
+ if (merge === "deep") {
951
+ mergedContext = utilities.deepMerge(currentStore.context, contextData);
952
+
953
+ mergedContext = structuredClone(mergedContext);
954
+ } else {
955
+
956
+ const clonedParent = structuredClone(currentStore.context);
957
+ mergedContext = { ...clonedParent, ...contextData };
958
+ }
959
+
960
+
961
+ const childInstanceID = `${slothlet.instanceID}__run_${Date.now()}_${Math.random().toString(36).slice(2, 9)}`;
962
+
963
+ const childStore = {
964
+ instanceID: childInstanceID,
965
+ context: mergedContext,
966
+ self: isolationMode === "full" ? utilities.deepClone(currentStore.self) : currentStore.self,
967
+ config: currentStore.config,
968
+ createdAt: currentStore.createdAt,
969
+ parentInstanceID: slothlet.instanceID
970
+ };
971
+
972
+
973
+ contextManager.instances.set(childInstanceID, childStore);
974
+
975
+ try {
976
+
977
+ return await contextManager.als.run(childStore, async () => {
978
+ return await fn(...args);
979
+ });
980
+ } finally {
981
+
982
+ contextManager.instances.delete(childInstanceID);
983
+ }
984
+ }
985
+
986
+ throw new slothlet.SlothletError("UNSUPPORTED_CONTEXT_MANAGER", {
987
+ manager: contextManager.constructor.name,
988
+ validationError: true
989
+ });
990
+ }
991
+ }.scope;
992
+ return scopeFunction;
993
+ }
994
+
995
+
996
+ createDestroyFunction(api) {
997
+ const slothlet = this.slothlet;
998
+ const destroyFunction = {
999
+ destroy: async () => {
1000
+
1001
+ if (slothlet.userHooks?.destroy && typeof slothlet.userHooks.destroy === "function") {
1002
+ await slothlet.userHooks.destroy();
1003
+ }
1004
+
1005
+
1006
+ if (api && typeof api.shutdown === "function") {
1007
+ await api.shutdown();
1008
+ } else {
1009
+
1010
+ await slothlet.shutdown();
1011
+ }
1012
+
1013
+
1014
+
1015
+
1016
+ slothlet.isDestroyed = true;
1017
+
1018
+
1019
+ const objectsToClear = [api, slothlet.api].filter((obj) => obj && typeof obj === "object");
1020
+
1021
+ for (const obj of objectsToClear) {
1022
+ const keys = Object.keys(obj);
1023
+ for (const key of keys) {
1024
+ try {
1025
+ delete obj[key];
1026
+ } catch (_) {
1027
+
1028
+ }
1029
+ }
1030
+ }
1031
+
1032
+
1033
+ slothlet.api = null;
1034
+ }
1035
+ }.destroy;
1036
+ return destroyFunction;
1037
+ }
1038
+
1039
+
1040
+ attachBuiltins(userApi, builtins) {
1041
+
1042
+
1043
+ Object.defineProperty(userApi, "slothlet", {
1044
+ value: builtins.slothlet,
1045
+ enumerable: true,
1046
+ writable: false,
1047
+ configurable: true
1048
+ });
1049
+
1050
+
1051
+ Object.defineProperty(userApi, "shutdown", {
1052
+ value: builtins.shutdown,
1053
+ enumerable: true,
1054
+ writable: false,
1055
+ configurable: true
1056
+ });
1057
+
1058
+
1059
+
1060
+
1061
+
1062
+
1063
+ if (builtins.destroy !== null) {
1064
+ Object.defineProperty(userApi, "destroy", {
1065
+ value: builtins.destroy,
1066
+ enumerable: true,
1067
+ writable: false,
1068
+ configurable: true
1069
+ });
1070
+ }
1071
+
1072
+ }
1073
+ }