@cldmv/slothlet 2.11.0 → 3.0.1
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.
- package/AGENT-USAGE.md +355 -325
- package/README.md +554 -238
- package/dist/lib/builders/api-assignment.mjs +605 -0
- package/dist/lib/builders/api_builder.mjs +1073 -0
- package/dist/lib/builders/builder.mjs +94 -0
- package/dist/lib/builders/modes-processor.mjs +1816 -0
- package/dist/lib/errors.mjs +227 -0
- package/dist/lib/factories/component-base.mjs +96 -0
- package/dist/lib/factories/context.mjs +38 -0
- package/dist/lib/handlers/api-cache-manager.mjs +216 -0
- package/dist/lib/handlers/api-manager.mjs +2364 -0
- package/dist/lib/handlers/context-async.mjs +184 -0
- package/dist/lib/handlers/context-live.mjs +184 -0
- package/dist/lib/handlers/hook-manager.mjs +789 -0
- package/dist/lib/handlers/lifecycle-token.mjs +44 -0
- package/dist/lib/handlers/lifecycle.mjs +131 -0
- package/dist/lib/handlers/materialize-manager.mjs +64 -0
- package/dist/lib/handlers/metadata.mjs +500 -0
- package/dist/lib/handlers/ownership.mjs +338 -0
- package/dist/lib/handlers/unified-wrapper.mjs +3031 -0
- package/dist/lib/helpers/class-instance-wrapper.mjs +125 -0
- package/dist/lib/helpers/config.mjs +343 -0
- package/dist/lib/helpers/eventemitter-context.mjs +365 -0
- package/dist/lib/helpers/hint-detector.mjs +63 -0
- package/dist/lib/helpers/modes-utils.mjs +53 -0
- package/dist/lib/helpers/resolve-from-caller.mjs +123 -117
- package/dist/lib/helpers/sanitize.mjs +247 -168
- package/dist/lib/helpers/utilities.mjs +46 -81
- package/dist/lib/i18n/languages/de-de.json +377 -0
- package/dist/lib/i18n/languages/en-gb.json +377 -0
- package/dist/lib/i18n/languages/en-us.json +377 -0
- package/dist/lib/i18n/languages/es-mx.json +377 -0
- package/dist/lib/i18n/languages/fr-fr.json +377 -0
- package/dist/lib/i18n/languages/hi-in.json +377 -0
- package/dist/lib/i18n/languages/ja-jp.json +377 -0
- package/dist/lib/i18n/languages/ko-kr.json +377 -0
- package/dist/lib/i18n/languages/pt-br.json +377 -0
- package/dist/lib/i18n/languages/ru-ru.json +377 -0
- package/dist/lib/i18n/languages/zh-cn.json +377 -0
- package/dist/lib/i18n/translations.mjs +140 -0
- package/dist/lib/modes/eager.mjs +75 -0
- package/dist/lib/modes/lazy.mjs +97 -0
- package/dist/lib/processors/flatten.mjs +453 -0
- package/dist/lib/processors/loader.mjs +355 -0
- package/dist/lib/processors/type-generator.mjs +291 -0
- package/dist/lib/processors/typescript.mjs +188 -0
- package/dist/lib/runtime/runtime-asynclocalstorage.mjs +80 -522
- package/dist/lib/runtime/runtime-livebindings.mjs +45 -390
- package/dist/lib/runtime/runtime.mjs +39 -159
- package/dist/slothlet.mjs +525 -744
- package/docs/API-RULES.md +338 -486
- package/index.cjs +4 -4
- package/index.mjs +82 -45
- package/package.json +143 -30
- package/types/dist/lib/builders/api-assignment.d.mts +97 -0
- package/types/dist/lib/builders/api-assignment.d.mts.map +1 -0
- package/types/dist/lib/builders/api_builder.d.mts +96 -0
- package/types/dist/lib/builders/api_builder.d.mts.map +1 -0
- package/types/dist/lib/builders/builder.d.mts +60 -0
- package/types/dist/lib/builders/builder.d.mts.map +1 -0
- package/types/dist/lib/builders/modes-processor.d.mts +32 -0
- package/types/dist/lib/builders/modes-processor.d.mts.map +1 -0
- package/types/dist/lib/errors.d.mts +118 -0
- package/types/dist/lib/errors.d.mts.map +1 -0
- package/types/dist/lib/factories/component-base.d.mts +182 -0
- package/types/dist/lib/factories/component-base.d.mts.map +1 -0
- package/types/dist/lib/factories/context.d.mts +26 -0
- package/types/dist/lib/factories/context.d.mts.map +1 -0
- package/types/dist/lib/handlers/api-cache-manager.d.mts +208 -0
- package/types/dist/lib/handlers/api-cache-manager.d.mts.map +1 -0
- package/types/dist/lib/handlers/api-manager.d.mts +392 -0
- package/types/dist/lib/handlers/api-manager.d.mts.map +1 -0
- package/types/dist/lib/handlers/context-async.d.mts +66 -0
- package/types/dist/lib/handlers/context-async.d.mts.map +1 -0
- package/types/dist/lib/handlers/context-live.d.mts +65 -0
- package/types/dist/lib/handlers/context-live.d.mts.map +1 -0
- package/types/dist/lib/handlers/hook-manager.d.mts +199 -0
- package/types/dist/lib/handlers/hook-manager.d.mts.map +1 -0
- package/types/dist/lib/handlers/lifecycle-token.d.mts +49 -0
- package/types/dist/lib/handlers/lifecycle-token.d.mts.map +1 -0
- package/types/dist/lib/handlers/lifecycle.d.mts +90 -0
- package/types/dist/lib/handlers/lifecycle.d.mts.map +1 -0
- package/types/dist/lib/handlers/materialize-manager.d.mts +75 -0
- package/types/dist/lib/handlers/materialize-manager.d.mts.map +1 -0
- package/types/dist/lib/handlers/metadata.d.mts +215 -0
- package/types/dist/lib/handlers/metadata.d.mts.map +1 -0
- package/types/dist/lib/handlers/ownership.d.mts +170 -0
- package/types/dist/lib/handlers/ownership.d.mts.map +1 -0
- package/types/dist/lib/handlers/unified-wrapper.d.mts +250 -0
- package/types/dist/lib/handlers/unified-wrapper.d.mts.map +1 -0
- package/types/dist/lib/helpers/class-instance-wrapper.d.mts +54 -0
- package/types/dist/lib/helpers/class-instance-wrapper.d.mts.map +1 -0
- package/types/dist/lib/helpers/config.d.mts +96 -0
- package/types/dist/lib/helpers/config.d.mts.map +1 -0
- package/types/dist/lib/helpers/eventemitter-context.d.mts +31 -0
- package/types/dist/lib/helpers/eventemitter-context.d.mts.map +1 -0
- package/types/dist/lib/helpers/hint-detector.d.mts +20 -0
- package/types/dist/lib/helpers/hint-detector.d.mts.map +1 -0
- package/types/dist/lib/helpers/modes-utils.d.mts +35 -0
- package/types/dist/lib/helpers/modes-utils.d.mts.map +1 -0
- package/types/dist/lib/helpers/resolve-from-caller.d.mts +29 -145
- package/types/dist/lib/helpers/resolve-from-caller.d.mts.map +1 -1
- package/types/dist/lib/helpers/sanitize.d.mts +95 -94
- package/types/dist/lib/helpers/sanitize.d.mts.map +1 -1
- package/types/dist/lib/helpers/utilities.d.mts +53 -116
- package/types/dist/lib/helpers/utilities.d.mts.map +1 -1
- package/types/dist/lib/i18n/translations.d.mts +39 -0
- package/types/dist/lib/i18n/translations.d.mts.map +1 -0
- package/types/dist/lib/modes/eager.d.mts +36 -0
- package/types/dist/lib/modes/eager.d.mts.map +1 -0
- package/types/dist/lib/modes/lazy.d.mts +49 -0
- package/types/dist/lib/modes/lazy.d.mts.map +1 -0
- package/types/dist/lib/processors/flatten.d.mts +114 -0
- package/types/dist/lib/processors/flatten.d.mts.map +1 -0
- package/types/dist/lib/processors/loader.d.mts +47 -0
- package/types/dist/lib/processors/loader.d.mts.map +1 -0
- package/types/dist/lib/processors/type-generator.d.mts +19 -0
- package/types/dist/lib/processors/type-generator.d.mts.map +1 -0
- package/types/dist/lib/processors/typescript.d.mts +55 -0
- package/types/dist/lib/processors/typescript.d.mts.map +1 -0
- package/types/dist/lib/runtime/runtime-asynclocalstorage.d.mts +47 -42
- package/types/dist/lib/runtime/runtime-asynclocalstorage.d.mts.map +1 -1
- package/types/dist/lib/runtime/runtime-livebindings.d.mts +34 -65
- package/types/dist/lib/runtime/runtime-livebindings.d.mts.map +1 -1
- package/types/dist/lib/runtime/runtime.d.mts +39 -9
- package/types/dist/lib/runtime/runtime.d.mts.map +1 -1
- package/types/dist/slothlet.d.mts +184 -111
- package/types/dist/slothlet.d.mts.map +1 -1
- package/types/index.d.mts +1 -3
- package/dist/lib/engine/README.md +0 -21
- package/dist/lib/engine/slothlet_child.mjs +0 -59
- package/dist/lib/engine/slothlet_engine.mjs +0 -372
- package/dist/lib/engine/slothlet_esm.mjs +0 -230
- package/dist/lib/engine/slothlet_helpers.mjs +0 -455
- package/dist/lib/engine/slothlet_worker.mjs +0 -149
- package/dist/lib/helpers/als-eventemitter.mjs +0 -256
- package/dist/lib/helpers/api_builder/add_api.mjs +0 -553
- package/dist/lib/helpers/api_builder/analysis.mjs +0 -532
- package/dist/lib/helpers/api_builder/construction.mjs +0 -495
- package/dist/lib/helpers/api_builder/decisions.mjs +0 -748
- package/dist/lib/helpers/api_builder/metadata.mjs +0 -248
- package/dist/lib/helpers/api_builder.mjs +0 -41
- package/dist/lib/helpers/auto-wrap.mjs +0 -62
- package/dist/lib/helpers/hooks.mjs +0 -389
- package/dist/lib/helpers/instance-manager.mjs +0 -111
- package/dist/lib/helpers/metadata-api.mjs +0 -201
- package/dist/lib/helpers/multidefault.mjs +0 -216
- package/dist/lib/modes/slothlet_eager.mjs +0 -154
- package/dist/lib/modes/slothlet_lazy.mjs +0 -594
- package/docs/API-RULES-CONDITIONS.md +0 -712
- package/types/dist/lib/engine/slothlet_child.d.mts +0 -2
- package/types/dist/lib/engine/slothlet_child.d.mts.map +0 -1
- package/types/dist/lib/engine/slothlet_engine.d.mts +0 -31
- package/types/dist/lib/engine/slothlet_engine.d.mts.map +0 -1
- package/types/dist/lib/engine/slothlet_esm.d.mts +0 -19
- package/types/dist/lib/engine/slothlet_esm.d.mts.map +0 -1
- package/types/dist/lib/engine/slothlet_helpers.d.mts +0 -25
- package/types/dist/lib/engine/slothlet_helpers.d.mts.map +0 -1
- package/types/dist/lib/engine/slothlet_worker.d.mts +0 -2
- package/types/dist/lib/engine/slothlet_worker.d.mts.map +0 -1
- package/types/dist/lib/helpers/als-eventemitter.d.mts +0 -56
- package/types/dist/lib/helpers/als-eventemitter.d.mts.map +0 -1
- package/types/dist/lib/helpers/api_builder/add_api.d.mts +0 -102
- package/types/dist/lib/helpers/api_builder/add_api.d.mts.map +0 -1
- package/types/dist/lib/helpers/api_builder/analysis.d.mts +0 -189
- package/types/dist/lib/helpers/api_builder/analysis.d.mts.map +0 -1
- package/types/dist/lib/helpers/api_builder/construction.d.mts +0 -107
- package/types/dist/lib/helpers/api_builder/construction.d.mts.map +0 -1
- package/types/dist/lib/helpers/api_builder/decisions.d.mts +0 -213
- package/types/dist/lib/helpers/api_builder/decisions.d.mts.map +0 -1
- package/types/dist/lib/helpers/api_builder/metadata.d.mts +0 -99
- package/types/dist/lib/helpers/api_builder/metadata.d.mts.map +0 -1
- package/types/dist/lib/helpers/api_builder.d.mts +0 -6
- package/types/dist/lib/helpers/api_builder.d.mts.map +0 -1
- package/types/dist/lib/helpers/auto-wrap.d.mts +0 -49
- package/types/dist/lib/helpers/auto-wrap.d.mts.map +0 -1
- package/types/dist/lib/helpers/hooks.d.mts +0 -342
- package/types/dist/lib/helpers/hooks.d.mts.map +0 -1
- package/types/dist/lib/helpers/instance-manager.d.mts +0 -41
- package/types/dist/lib/helpers/instance-manager.d.mts.map +0 -1
- package/types/dist/lib/helpers/metadata-api.d.mts +0 -132
- package/types/dist/lib/helpers/metadata-api.d.mts.map +0 -1
- package/types/dist/lib/helpers/multidefault.d.mts +0 -90
- package/types/dist/lib/helpers/multidefault.d.mts.map +0 -1
- package/types/dist/lib/modes/slothlet_eager.d.mts +0 -65
- package/types/dist/lib/modes/slothlet_eager.d.mts.map +0 -1
- package/types/dist/lib/modes/slothlet_lazy.d.mts +0 -31
- package/types/dist/lib/modes/slothlet_lazy.d.mts.map +0 -1
- package/types/index.d.mts.map +0 -1
package/dist/slothlet.mjs
CHANGED
|
@@ -17,924 +17,705 @@
|
|
|
17
17
|
|
|
18
18
|
|
|
19
19
|
|
|
20
|
-
import
|
|
21
|
-
import
|
|
20
|
+
import { readdirSync } from "node:fs";
|
|
21
|
+
import { dirname, join } from "node:path";
|
|
22
22
|
import { fileURLToPath, pathToFileURL } from "node:url";
|
|
23
|
-
|
|
24
|
-
import {
|
|
23
|
+
import { getContextManager } from "@cldmv/slothlet/factories/context";
|
|
24
|
+
import { SlothletError, SlothletWarning, SlothletDebug } from "@cldmv/slothlet/errors";
|
|
25
|
+
import { registerInstance } from "@cldmv/slothlet/handlers/lifecycle-token";
|
|
26
|
+
import { initI18n } from "@cldmv/slothlet/i18n";
|
|
25
27
|
import {
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
safeDefine,
|
|
32
|
-
deepMerge,
|
|
33
|
-
mutateLiveBindingFunction,
|
|
34
|
-
addApiFromFolder
|
|
35
|
-
} from "@cldmv/slothlet/helpers/api_builder";
|
|
36
|
-
import { updateInstanceData, cleanupInstance } from "@cldmv/slothlet/helpers/instance-manager";
|
|
37
|
-
import { disableAlsForEventEmitters, cleanupAllSlothletListeners } from "@cldmv/slothlet/helpers/als-eventemitter";
|
|
38
|
-
import { HookManager } from "@cldmv/slothlet/helpers/hooks";
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
function normalizeRuntimeType(runtime) {
|
|
44
|
-
if (!runtime || typeof runtime !== "string") {
|
|
45
|
-
return "async";
|
|
46
|
-
}
|
|
28
|
+
enableEventEmitterPatching,
|
|
29
|
+
disableEventEmitterPatching,
|
|
30
|
+
cleanupEventEmitterResources,
|
|
31
|
+
setApiContextChecker
|
|
32
|
+
} from "@cldmv/slothlet/helpers/eventemitter-context";
|
|
47
33
|
|
|
48
|
-
const normalized = runtime.toLowerCase().trim();
|
|
49
34
|
|
|
35
|
+
class Slothlet {
|
|
50
36
|
|
|
51
|
-
if (normalized === "async" || normalized === "asynclocal" || normalized === "asynclocalstorage") {
|
|
52
|
-
return "async";
|
|
53
|
-
}
|
|
54
|
-
|
|
55
37
|
|
|
56
|
-
|
|
57
|
-
return "live";
|
|
58
|
-
}
|
|
38
|
+
static RESERVED_ROOT_KEYS = ["slothlet", "shutdown", "destroy"];
|
|
59
39
|
|
|
60
40
|
|
|
61
|
-
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
const __filename = fileURLToPath(import.meta.url);
|
|
65
|
-
const __dirname = path.dirname(__filename);
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
let DEBUG = process.argv.includes("--slothletdebug")
|
|
72
|
-
? true
|
|
73
|
-
: process.env.SLOTHLET_DEBUG === "1" || process.env.SLOTHLET_DEBUG === "true"
|
|
74
|
-
? true
|
|
75
|
-
: false;
|
|
76
|
-
|
|
41
|
+
static SKIP_PROPS = ["__metadata", "__type", "_materialize", "_impl", "____slothletInternal"];
|
|
77
42
|
|
|
78
|
-
|
|
79
|
-
process.env.SLOTHLET_DEBUG = "1";
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
export const self = {};
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
export const context = {};
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
export const reference = {};
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
async function slothlet(options = {}) {
|
|
93
|
-
|
|
94
|
-
const instance = createFreshInstance();
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
for (const key of Object.keys(slothlet)) {
|
|
98
|
-
if (key.startsWith("_")) continue;
|
|
43
|
+
constructor() {
|
|
99
44
|
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
}
|
|
106
|
-
}
|
|
45
|
+
this.SlothletError = SlothletError;
|
|
46
|
+
this.SlothletWarning = SlothletWarning;
|
|
47
|
+
|
|
48
|
+
this.debugLogger = null;
|
|
107
49
|
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
}
|
|
118
|
-
Object.defineProperty(slothlet, "_instance", { value: instance, writable: false, enumerable: false, configurable: true });
|
|
50
|
+
|
|
51
|
+
this.instanceID = null;
|
|
52
|
+
this.config = null;
|
|
53
|
+
this.api = null;
|
|
54
|
+
this.boundApi = null;
|
|
55
|
+
this.contextManager = null;
|
|
56
|
+
this.isLoaded = false;
|
|
57
|
+
this.reference = null;
|
|
58
|
+
this.context = null;
|
|
119
59
|
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
60
|
+
|
|
61
|
+
this._totalLazyCount = 0;
|
|
62
|
+
this._unmaterializedLazyCount = 0;
|
|
63
|
+
this._materializationComplete = false;
|
|
64
|
+
this._materializationWaiters = [];
|
|
65
|
+
this._materializationCompleteEmitted = false;
|
|
123
66
|
|
|
67
|
+
|
|
68
|
+
this.componentCategories = ["helpers", "handlers", "builders", "processors", "modes"];
|
|
124
69
|
|
|
125
|
-
function createFreshInstance() {
|
|
126
|
-
const instance = {};
|
|
127
|
-
for (const [k, v] of Object.entries(slothletObject)) {
|
|
128
|
-
if (typeof v === "function") {
|
|
129
|
-
|
|
130
|
-
instance[k] = v;
|
|
131
|
-
continue;
|
|
132
|
-
}
|
|
133
70
|
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
71
|
+
for (const category of this.componentCategories) {
|
|
72
|
+
this[category] = {};
|
|
73
|
+
}
|
|
137
74
|
}
|
|
138
|
-
return instance;
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
const slothletObject = {
|
|
143
|
-
|
|
144
|
-
api: null,
|
|
145
|
-
self: {},
|
|
146
|
-
boundapi: {},
|
|
147
|
-
context: {},
|
|
148
|
-
reference: {},
|
|
149
|
-
mode: "singleton",
|
|
150
|
-
loaded: false,
|
|
151
|
-
config: {
|
|
152
|
-
lazy: false,
|
|
153
|
-
apiDepth: Infinity,
|
|
154
|
-
debug: DEBUG,
|
|
155
|
-
dir: null,
|
|
156
|
-
sanitize: null,
|
|
157
|
-
allowApiOverwrite: true,
|
|
158
|
-
enableModuleOwnership: false
|
|
159
|
-
},
|
|
160
|
-
|
|
161
|
-
_moduleOwnership: new Map(),
|
|
162
|
-
_dispose: null,
|
|
163
|
-
_boundAPIShutdown: null,
|
|
164
|
-
instanceId: null,
|
|
165
75
|
|
|
166
76
|
|
|
167
|
-
async
|
|
168
|
-
if (this.loaded) {
|
|
169
|
-
console.warn("[slothlet] create: API already loaded, returning existing instance.");
|
|
170
|
-
return this.boundapi;
|
|
171
|
-
}
|
|
172
|
-
|
|
77
|
+
async _initializeComponents() {
|
|
173
78
|
|
|
174
79
|
|
|
175
80
|
|
|
176
|
-
const { entry = import.meta.url, engine = "singleton", mode, api_mode = "auto" } = options ?? {};
|
|
177
|
-
|
|
178
81
|
|
|
179
|
-
const executionEngine = mode && ["singleton", "vm", "worker", "fork"].includes(mode) ? mode : engine;
|
|
180
|
-
|
|
181
82
|
|
|
182
|
-
let isLazyMode;
|
|
183
|
-
if (mode && ["lazy", "eager"].includes(mode)) {
|
|
184
|
-
isLazyMode = mode === "lazy";
|
|
185
|
-
} else {
|
|
186
|
-
isLazyMode = options.lazy !== undefined ? options.lazy : this.config.lazy;
|
|
187
|
-
}
|
|
188
83
|
|
|
189
|
-
|
|
190
|
-
const runtimeType = normalizeRuntimeType(options.runtime || "async");
|
|
191
|
-
const loadingModeStr = isLazyMode ? "lazy" : "eager";
|
|
192
|
-
this.instanceId = `slothlet_${runtimeType}_${loadingModeStr}_${Date.now()}_${Math.random().toString(36).slice(2, 11).padEnd(9, "0")}`;
|
|
84
|
+
const baseDir = join(dirname(fileURLToPath(import.meta.url)), "lib");
|
|
193
85
|
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
const modesDir = path.join(__dirname, "lib", "modes");
|
|
86
|
+
for (const category of this.componentCategories) {
|
|
87
|
+
const categoryDir = join(baseDir, category);
|
|
88
|
+
const files = readdirSync(categoryDir).filter((f) => f.endsWith(".mjs"));
|
|
198
89
|
|
|
199
|
-
const
|
|
200
|
-
|
|
90
|
+
for (const file of files) {
|
|
91
|
+
const filePath = join(categoryDir, file);
|
|
201
92
|
|
|
202
|
-
for (const file of modeFiles) {
|
|
203
|
-
const modePath = file;
|
|
204
|
-
|
|
205
|
-
const modeName = path.parse(file).name.replace(/^slothlet_/, "");
|
|
206
|
-
if (!modeName || modeName.includes(" ")) continue;
|
|
207
93
|
try {
|
|
94
|
+
const module = await import(pathToFileURL(filePath).href);
|
|
95
|
+
|
|
208
96
|
|
|
209
|
-
const
|
|
97
|
+
const classExports = Object.values(module).filter((exp) => typeof exp === "function" && exp.slothletProperty);
|
|
210
98
|
|
|
211
|
-
const
|
|
212
|
-
|
|
213
|
-
|
|
99
|
+
for (const ClassExport of classExports) {
|
|
100
|
+
const propName = ClassExport.slothletProperty;
|
|
101
|
+
|
|
102
|
+
this[category][propName] = new ClassExport(this);
|
|
103
|
+
|
|
104
|
+
if (this.config?.debug?.initialization) {
|
|
105
|
+
this.debug("initialization", {
|
|
106
|
+
key: "DEBUG_MODE_COMPONENT_INITIALIZED",
|
|
107
|
+
component: ClassExport.name,
|
|
108
|
+
category,
|
|
109
|
+
propertyName: propName
|
|
110
|
+
});
|
|
111
|
+
}
|
|
214
112
|
}
|
|
215
|
-
} catch (
|
|
216
|
-
|
|
113
|
+
} catch (error) {
|
|
114
|
+
|
|
115
|
+
|
|
116
|
+
|
|
117
|
+
|
|
118
|
+
throw new this.SlothletError(
|
|
119
|
+
"MODULE_IMPORT_FAILED",
|
|
120
|
+
{
|
|
121
|
+
modulePath: filePath
|
|
122
|
+
},
|
|
123
|
+
error
|
|
124
|
+
);
|
|
217
125
|
}
|
|
218
126
|
}
|
|
219
127
|
}
|
|
128
|
+
}
|
|
220
129
|
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
if (
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
this.context = context;
|
|
230
|
-
this.reference = reference;
|
|
130
|
+
|
|
131
|
+
_setupLifecycleSubscribers() {
|
|
132
|
+
|
|
133
|
+
|
|
134
|
+
if (!this.handlers.lifecycle) {
|
|
135
|
+
return;
|
|
136
|
+
}
|
|
137
|
+
|
|
231
138
|
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
139
|
+
|
|
140
|
+
|
|
141
|
+
|
|
142
|
+
if (this.handlers.metadata) {
|
|
143
|
+
this.handlers.lifecycle.subscribe("impl:created", (data, token) => {
|
|
144
|
+
this.handlers.metadata.tagSystemMetadata(
|
|
145
|
+
data.impl,
|
|
146
|
+
{
|
|
147
|
+
filePath: data.filePath,
|
|
148
|
+
apiPath: data.apiPath,
|
|
149
|
+
moduleID: data.moduleID,
|
|
150
|
+
sourceFolder: data.sourceFolder
|
|
151
|
+
},
|
|
152
|
+
token
|
|
153
|
+
);
|
|
154
|
+
});
|
|
155
|
+
|
|
156
|
+
this.handlers.lifecycle.subscribe("impl:changed", (data, token) => {
|
|
157
|
+
this.handlers.metadata.tagSystemMetadata(
|
|
158
|
+
data.impl,
|
|
159
|
+
{
|
|
160
|
+
filePath: data.filePath,
|
|
161
|
+
apiPath: data.apiPath,
|
|
162
|
+
moduleID: data.moduleID,
|
|
163
|
+
sourceFolder: data.sourceFolder
|
|
164
|
+
},
|
|
165
|
+
token
|
|
166
|
+
);
|
|
167
|
+
});
|
|
236
168
|
|
|
237
|
-
|
|
169
|
+
this.handlers.lifecycle.subscribe("impl:removed", (data) => {
|
|
238
170
|
|
|
239
|
-
hooksEnabled = hooks;
|
|
240
|
-
hooksPattern = hooks ? "**" : null;
|
|
241
|
-
} else if (typeof hooks === "string") {
|
|
242
171
|
|
|
243
|
-
hooksEnabled = true;
|
|
244
|
-
hooksPattern = hooks;
|
|
245
|
-
} else if (hooks && typeof hooks === "object") {
|
|
246
172
|
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
}
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
this.hookManager = new HookManager(hooksEnabled, hooksPattern, { suppressErrors: hooksSuppressErrors });
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
if (scope && typeof scope === "object") {
|
|
257
|
-
const mergeStrategy = scope.merge || "shallow";
|
|
258
|
-
if (mergeStrategy !== "shallow" && mergeStrategy !== "deep") {
|
|
259
|
-
throw new TypeError(`Invalid scope.merge value: "${mergeStrategy}". Must be "shallow" or "deep".`);
|
|
173
|
+
if (data.apiPath) {
|
|
174
|
+
const rootSegment = data.apiPath.split(".")[0];
|
|
175
|
+
this.handlers.metadata.removeUserMetadataByApiPath(rootSegment);
|
|
260
176
|
}
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
this.config.scope = { enabled: false };
|
|
264
|
-
} else {
|
|
265
|
-
|
|
266
|
-
this.config.scope = { merge: "shallow" };
|
|
267
|
-
}
|
|
177
|
+
});
|
|
178
|
+
}
|
|
268
179
|
|
|
180
|
+
|
|
181
|
+
|
|
182
|
+
|
|
183
|
+
if (this.handlers.ownership) {
|
|
269
184
|
|
|
270
|
-
if (sanitize !== null) {
|
|
271
|
-
this.config.sanitize = sanitize;
|
|
272
|
-
}
|
|
273
|
-
|
|
274
185
|
|
|
275
|
-
|
|
186
|
+
this.handlers.lifecycle.subscribe("impl:created", (data) => {
|
|
187
|
+
|
|
188
|
+
|
|
189
|
+
|
|
190
|
+
const collisionMode = this.config?.collision?.api || "merge";
|
|
191
|
+
|
|
192
|
+
const implValue = data.wrapper?.__impl ?? data.impl;
|
|
193
|
+
this.handlers.ownership.register({
|
|
194
|
+
moduleID: data.moduleID,
|
|
195
|
+
apiPath: data.apiPath,
|
|
196
|
+
value: implValue,
|
|
197
|
+
source: data.source,
|
|
198
|
+
filePath: data.filePath,
|
|
199
|
+
collisionMode: collisionMode
|
|
200
|
+
});
|
|
201
|
+
});
|
|
276
202
|
|
|
277
203
|
|
|
278
204
|
|
|
279
|
-
|
|
280
|
-
this.boundapi = function (...args) {
|
|
281
|
-
if (typeof this.boundapi._impl === "function") {
|
|
282
|
-
return this.boundapi._impl(...args);
|
|
283
|
-
}
|
|
284
|
-
}.bind(this);
|
|
285
|
-
this.boundapi._impl = () => {};
|
|
286
|
-
} else if (this.api_mode === "auto") {
|
|
205
|
+
this.handlers.lifecycle.subscribe("impl:changed", (data) => {
|
|
287
206
|
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
this.
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
207
|
+
|
|
208
|
+
|
|
209
|
+
const collisionMode = this.config?.collision?.api || "merge";
|
|
210
|
+
|
|
211
|
+
|
|
212
|
+
|
|
213
|
+
const implValue = data.wrapper?.__impl ?? data.impl;
|
|
294
214
|
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
});
|
|
310
|
-
}
|
|
311
|
-
this._dispose = dispose;
|
|
312
|
-
this.loaded = true;
|
|
313
|
-
return api;
|
|
215
|
+
|
|
216
|
+
|
|
217
|
+
const currentOwner = this.handlers.ownership.getCurrentOwner(data.apiPath);
|
|
218
|
+
if (currentOwner?.moduleID !== data.moduleID) {
|
|
219
|
+
this.handlers.ownership.register({
|
|
220
|
+
moduleID: data.moduleID,
|
|
221
|
+
apiPath: data.apiPath,
|
|
222
|
+
value: implValue,
|
|
223
|
+
source: data.source,
|
|
224
|
+
filePath: data.filePath,
|
|
225
|
+
collisionMode: collisionMode
|
|
226
|
+
});
|
|
227
|
+
}
|
|
228
|
+
});
|
|
314
229
|
}
|
|
315
|
-
}
|
|
230
|
+
}
|
|
316
231
|
|
|
317
232
|
|
|
318
|
-
|
|
319
|
-
this.
|
|
233
|
+
_registerLazyWrapper() {
|
|
234
|
+
this._totalLazyCount++;
|
|
235
|
+
this._unmaterializedLazyCount++;
|
|
236
|
+
|
|
237
|
+
if (this.config?.debug?.materialize) {
|
|
238
|
+
this.debug("materialize", {
|
|
239
|
+
key: "DEBUG_MODE_LAZY_WRAPPER_REGISTERED",
|
|
240
|
+
total: this._totalLazyCount,
|
|
241
|
+
unmaterialized: this._unmaterializedLazyCount
|
|
242
|
+
});
|
|
243
|
+
}
|
|
244
|
+
}
|
|
320
245
|
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
246
|
+
|
|
247
|
+
_onWrapperMaterialized() {
|
|
248
|
+
this._unmaterializedLazyCount--;
|
|
249
|
+
|
|
250
|
+
if (this.config?.debug?.materialize) {
|
|
251
|
+
this.debug("materialize", {
|
|
252
|
+
key: "DEBUG_MODE_LAZY_WRAPPER_MATERIALIZED",
|
|
253
|
+
total: this._totalLazyCount,
|
|
254
|
+
unmaterialized: this._unmaterializedLazyCount,
|
|
328
255
|
|
|
329
|
-
|
|
330
|
-
|
|
256
|
+
|
|
257
|
+
percentage: this._totalLazyCount > 0 ? ((this._totalLazyCount - this._unmaterializedLazyCount) / this._totalLazyCount) * 100 : 100
|
|
258
|
+
});
|
|
331
259
|
}
|
|
332
260
|
|
|
333
|
-
let apiDir = this.config.dir || "api";
|
|
334
261
|
|
|
335
|
-
if (
|
|
336
|
-
|
|
337
|
-
}
|
|
338
|
-
|
|
339
|
-
if (this.loaded) return this.api;
|
|
340
|
-
if (this.config.lazy) {
|
|
341
|
-
this.api = await this.modes.lazy.create.call(this, apiDir, this.config.apiDepth || Infinity, 0);
|
|
342
|
-
} else {
|
|
343
|
-
this.api = await this.modes.eager.create.call(this, apiDir, this.config.apiDepth || Infinity, 0);
|
|
344
|
-
}
|
|
262
|
+
if (this._unmaterializedLazyCount === 0 && !this._materializationComplete) {
|
|
263
|
+
this._materializationComplete = true;
|
|
345
264
|
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
disable: () => this.hookManager.disable(),
|
|
353
|
-
clear: (type) => this.hookManager.clear(type),
|
|
354
|
-
list: (type) => this.hookManager.list(type)
|
|
355
|
-
};
|
|
265
|
+
if (this.config?.debug?.materialize) {
|
|
266
|
+
this.debug("materialize", {
|
|
267
|
+
key: "DEBUG_MODE_ALL_LAZY_WRAPPERS_MATERIALIZED",
|
|
268
|
+
total: this._totalLazyCount
|
|
269
|
+
});
|
|
270
|
+
}
|
|
356
271
|
|
|
357
272
|
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
enumerable: true,
|
|
362
|
-
configurable: true
|
|
363
|
-
});
|
|
364
|
-
}
|
|
365
|
-
|
|
366
|
-
if (this.config.debug) console.log(this.api);
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
if (this.api_mode === "auto") {
|
|
370
|
-
this.api_mode = typeof this.api === "function" ? "function" : "object";
|
|
371
|
-
if (this.config.debug) {
|
|
372
|
-
console.log(`[DEBUG] Auto-detected api_mode: ${this.api_mode} (API is ${typeof this.api})`);
|
|
273
|
+
const waiters = this._materializationWaiters.splice(0);
|
|
274
|
+
for (const resolve of waiters) {
|
|
275
|
+
resolve();
|
|
373
276
|
}
|
|
374
277
|
|
|
375
278
|
|
|
376
|
-
if (this.
|
|
377
|
-
this.
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
279
|
+
if (this.config?.tracking?.materialization && !this._materializationCompleteEmitted) {
|
|
280
|
+
this._materializationCompleteEmitted = true;
|
|
281
|
+
|
|
282
|
+
|
|
283
|
+
if (this.handlers?.lifecycle) {
|
|
284
|
+
this.handlers.lifecycle.emit("materialized:complete", {
|
|
285
|
+
total: this._totalLazyCount,
|
|
286
|
+
timestamp: Date.now()
|
|
287
|
+
});
|
|
288
|
+
}
|
|
386
289
|
}
|
|
387
290
|
}
|
|
388
|
-
|
|
389
|
-
const l_ctxRef = { ...{ context: null, reference: null }, ...ctxRef };
|
|
390
|
-
|
|
391
|
-
const _boundapi = this.createBoundApi(l_ctxRef.reference);
|
|
392
|
-
|
|
393
|
-
mutateLiveBindingFunction(this.boundapi, _boundapi);
|
|
394
|
-
|
|
395
|
-
this.updateBindings(this.context, this.reference, this.boundapi);
|
|
396
|
-
|
|
397
|
-
this.loaded = true;
|
|
398
|
-
|
|
399
|
-
return this.boundapi;
|
|
400
|
-
},
|
|
291
|
+
}
|
|
401
292
|
|
|
402
293
|
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
294
|
+
async load(config = {}, preservedInstanceID = null) {
|
|
295
|
+
|
|
296
|
+
this.config = config;
|
|
406
297
|
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
298
|
+
|
|
299
|
+
|
|
300
|
+
|
|
301
|
+
this.debugLogger = new SlothletDebug(config);
|
|
410
302
|
|
|
411
303
|
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
maxDepth,
|
|
415
|
-
mode,
|
|
416
|
-
subdirHandler,
|
|
417
|
-
instance: this,
|
|
418
|
-
existingApi
|
|
419
|
-
});
|
|
420
|
-
},
|
|
304
|
+
|
|
305
|
+
await this._initializeComponents();
|
|
421
306
|
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
return this._buildCategory(categoryPath, { currentDepth, maxDepth, mode: "eager" });
|
|
425
|
-
},
|
|
307
|
+
|
|
308
|
+
registerInstance(this);
|
|
426
309
|
|
|
427
|
-
|
|
428
|
-
async _loadSingleModule(modulePath, returnAnalysis = false) {
|
|
429
310
|
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
const processedModule = processModuleFromAnalysis(analysis, {
|
|
435
|
-
debug: this.config.debug,
|
|
436
|
-
instance: this
|
|
437
|
-
});
|
|
311
|
+
this._setupLifecycleSubscribers();
|
|
312
|
+
|
|
313
|
+
|
|
314
|
+
this.config = this.helpers.config.transformConfig(config);
|
|
438
315
|
|
|
439
316
|
|
|
440
|
-
if (
|
|
441
|
-
|
|
317
|
+
if (this.config?.i18n?.language) {
|
|
318
|
+
initI18n({ language: this.config.i18n.language });
|
|
442
319
|
}
|
|
443
320
|
|
|
444
321
|
|
|
445
|
-
|
|
446
|
-
|
|
322
|
+
|
|
323
|
+
this.debugLogger = new SlothletDebug(this.config);
|
|
447
324
|
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
return shouldIncludeFile(entry);
|
|
451
|
-
},
|
|
325
|
+
|
|
326
|
+
this.instanceID = preservedInstanceID || this.helpers.utilities.generateId();
|
|
452
327
|
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
try {
|
|
457
|
-
|
|
458
|
-
Object.defineProperty(this.boundapi, key, {
|
|
459
|
-
value: materializedValue,
|
|
460
|
-
writable: true,
|
|
461
|
-
enumerable: true,
|
|
462
|
-
configurable: true
|
|
463
|
-
});
|
|
328
|
+
|
|
329
|
+
this.reference = this.config.reference;
|
|
330
|
+
this.context = this.config.context;
|
|
464
331
|
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
Object.defineProperty(self, key, {
|
|
468
|
-
value: materializedValue,
|
|
469
|
-
writable: true,
|
|
470
|
-
enumerable: true,
|
|
471
|
-
configurable: true
|
|
472
|
-
});
|
|
473
|
-
}
|
|
332
|
+
|
|
333
|
+
this.contextManager = getContextManager(this.config.runtime);
|
|
474
334
|
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
335
|
+
|
|
336
|
+
|
|
337
|
+
|
|
338
|
+
|
|
339
|
+
|
|
340
|
+
|
|
341
|
+
|
|
342
|
+
|
|
343
|
+
setApiContextChecker(() => {
|
|
344
|
+
|
|
345
|
+
const ctx = this.contextManager.tryGetContext();
|
|
346
|
+
return !!(ctx && ctx.self);
|
|
347
|
+
|
|
348
|
+
});
|
|
349
|
+
|
|
481
350
|
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
351
|
+
|
|
352
|
+
let store;
|
|
353
|
+
if (preservedInstanceID && this.contextManager.instances.has(preservedInstanceID)) {
|
|
354
|
+
|
|
355
|
+
this.contextManager.cleanup(preservedInstanceID);
|
|
356
|
+
store = this.contextManager.initialize(this.instanceID, this.config);
|
|
357
|
+
} else {
|
|
358
|
+
|
|
359
|
+
store = this.contextManager.initialize(this.instanceID, this.config);
|
|
490
360
|
}
|
|
491
|
-
},
|
|
492
361
|
|
|
493
|
-
|
|
494
|
-
updateBindings(newContext = null, newReference = null, newSelf = null) {
|
|
495
|
-
if (newContext === null || (typeof newContext === "object" && Object.keys(newContext).length === 0)) newContext = { ...context };
|
|
496
|
-
if (newReference === null || (typeof newReference === "object" && Object.keys(newReference).length === 0))
|
|
497
|
-
newReference = { ...reference };
|
|
498
|
-
if (newSelf === null || (typeof newSelf === "object" && Object.keys(newSelf).length === 0)) newSelf = this.boundapi;
|
|
499
|
-
|
|
500
362
|
|
|
501
363
|
|
|
364
|
+
enableEventEmitterPatching();
|
|
502
365
|
|
|
503
|
-
|
|
366
|
+
|
|
367
|
+
|
|
368
|
+
|
|
369
|
+
if (typeof this.contextManager.registerEventEmitterContextChecker === "function") {
|
|
370
|
+
this.contextManager.registerEventEmitterContextChecker();
|
|
371
|
+
}
|
|
504
372
|
|
|
505
373
|
|
|
506
|
-
const contextWithRuntime = {
|
|
507
|
-
...newContext,
|
|
508
|
-
runtimeType: this.config.runtime
|
|
509
|
-
};
|
|
510
|
-
Object.assign(context, contextWithRuntime || {});
|
|
511
|
-
Object.assign(reference, newReference || {});
|
|
512
374
|
|
|
513
375
|
|
|
514
|
-
|
|
515
|
-
updateInstanceData(this.instanceId, "self", newSelf);
|
|
516
|
-
updateInstanceData(this.instanceId, "context", contextWithRuntime);
|
|
517
|
-
updateInstanceData(this.instanceId, "reference", newReference);
|
|
518
|
-
updateInstanceData(this.instanceId, "config", this.config);
|
|
519
|
-
}
|
|
376
|
+
const baseModuleId = `base_${this.helpers.utilities.generateId().substring(0, 8)}`;
|
|
520
377
|
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
378
|
+
|
|
379
|
+
|
|
380
|
+
const baseApi = await this.builders.builder.buildAPI({
|
|
381
|
+
dir: this.config.dir,
|
|
382
|
+
mode: this.config.mode,
|
|
383
|
+
moduleID: baseModuleId
|
|
526
384
|
});
|
|
527
|
-
},
|
|
528
385
|
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
let boundApi;
|
|
386
|
+
|
|
387
|
+
|
|
388
|
+
this.api = baseApi;
|
|
534
389
|
|
|
535
|
-
|
|
390
|
+
|
|
391
|
+
const apiWithBuiltins = await this.buildFinalAPI(this.api);
|
|
536
392
|
|
|
537
393
|
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
394
|
+
|
|
395
|
+
|
|
396
|
+
|
|
397
|
+
if (this.handlers.apiCacheManager) {
|
|
398
|
+
this.handlers.apiCacheManager.set(baseModuleId, {
|
|
399
|
+
endpoint: ".",
|
|
400
|
+
moduleID: baseModuleId,
|
|
401
|
+
api: this.api,
|
|
402
|
+
folderPath: this.config.dir,
|
|
403
|
+
mode: this.config.mode,
|
|
404
|
+
sanitizeOptions: this.config.sanitize || {},
|
|
405
|
+
|
|
406
|
+
|
|
407
|
+
collisionMode: this.config.collision?.api || "merge",
|
|
408
|
+
config: { ...this.config },
|
|
409
|
+
timestamp: Date.now()
|
|
410
|
+
});
|
|
548
411
|
}
|
|
549
412
|
|
|
550
413
|
|
|
551
|
-
|
|
552
|
-
|
|
414
|
+
this.injectRuntimeMetadataFunctions(apiWithBuiltins);
|
|
415
|
+
|
|
416
|
+
|
|
417
|
+
if (this.config.metadata && typeof this.config.metadata === "object") {
|
|
553
418
|
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
return Reflect.ownKeys(boundApi);
|
|
557
|
-
}
|
|
558
|
-
|
|
559
|
-
async function resolveAll(obj) {
|
|
560
|
-
const keys = Reflect.ownKeys(obj);
|
|
561
|
-
const entries = await Promise.all(
|
|
562
|
-
keys.map(async (key) => {
|
|
563
|
-
const value = obj[key];
|
|
564
|
-
|
|
565
|
-
if (typeof value === "function" && value.constructor.name === "Proxy") {
|
|
566
|
-
let resolved;
|
|
567
|
-
try {
|
|
568
|
-
resolved = await value();
|
|
569
|
-
} catch {
|
|
570
|
-
resolved = value;
|
|
571
|
-
}
|
|
572
|
-
|
|
573
|
-
if (resolved && typeof resolved === "object" && !Array.isArray(resolved)) {
|
|
574
|
-
return [key, await resolveAll(resolved)];
|
|
575
|
-
}
|
|
576
|
-
return [key, resolved];
|
|
577
|
-
} else if (value && typeof value === "object" && !Array.isArray(value)) {
|
|
578
|
-
|
|
579
|
-
return [key, await resolveAll(value)];
|
|
580
|
-
} else {
|
|
581
|
-
return [key, value];
|
|
582
|
-
}
|
|
583
|
-
})
|
|
584
|
-
);
|
|
585
|
-
const apiObj = {};
|
|
586
|
-
for (const [key, val] of entries) {
|
|
587
|
-
apiObj[key] = val;
|
|
588
|
-
}
|
|
589
|
-
return apiObj;
|
|
590
|
-
}
|
|
591
|
-
return resolveAll(boundApi);
|
|
419
|
+
for (const [key, value] of Object.entries(this.config.metadata)) {
|
|
420
|
+
this.handlers.metadata.setGlobalMetadata(key, value);
|
|
592
421
|
}
|
|
422
|
+
|
|
593
423
|
|
|
594
|
-
|
|
595
|
-
}
|
|
424
|
+
this.handlers.metadata.registerUserMetadata(baseModuleId, this.config.metadata);
|
|
425
|
+
}
|
|
596
426
|
|
|
597
427
|
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
boundApi.shutdown.toString().indexOf("[native code]") === -1 &&
|
|
604
|
-
boundApi.shutdown.toString() !== this.shutdown.bind(this).toString()
|
|
605
|
-
) {
|
|
606
|
-
this._boundAPIShutdown = boundApi.shutdown;
|
|
607
|
-
} else {
|
|
608
|
-
this._boundAPIShutdown = null;
|
|
428
|
+
|
|
429
|
+
|
|
430
|
+
|
|
431
|
+
if (this.handlers.ownership) {
|
|
432
|
+
this.handlers.ownership.registerSubtree(apiWithBuiltins, baseModuleId, "");
|
|
609
433
|
}
|
|
610
434
|
|
|
611
435
|
|
|
612
436
|
|
|
613
|
-
|
|
614
|
-
const hasUserDefinedShutdown = this._boundAPIShutdown !== null;
|
|
615
437
|
|
|
616
|
-
|
|
617
|
-
if (!
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
438
|
+
|
|
439
|
+
if (!this.boundApi) {
|
|
440
|
+
|
|
441
|
+
|
|
442
|
+
|
|
443
|
+
const isCallable = typeof this.api === "function" || (this.api && typeof this.api.default === "function");
|
|
444
|
+
const proxyTarget = isCallable ? function () {} : {};
|
|
445
|
+
|
|
446
|
+
this.boundApi = new Proxy(proxyTarget, {
|
|
447
|
+
get: (target, prop) => (this.api ? this.api[prop] : undefined),
|
|
448
|
+
set: (target, prop, value) => {
|
|
449
|
+
if (this.api) {
|
|
450
|
+
this.api[prop] = value;
|
|
451
|
+
}
|
|
452
|
+
return true;
|
|
453
|
+
},
|
|
454
|
+
has: (target, prop) => (this.api ? prop in this.api : false),
|
|
455
|
+
ownKeys: (____target) => (this.api ? Reflect.ownKeys(this.api) : []),
|
|
456
|
+
deleteProperty: (target, prop) => (this.api ? delete this.api[prop] : true),
|
|
457
|
+
apply: (target, thisArg, args) => (this.api ? Reflect.apply(this.api, thisArg, args) : undefined),
|
|
458
|
+
construct: (target, args) => (this.api ? Reflect.construct(this.api, args) : {}),
|
|
459
|
+
getOwnPropertyDescriptor: (target, prop) => {
|
|
460
|
+
|
|
461
|
+
if (isCallable && prop === "prototype") {
|
|
462
|
+
return Object.getOwnPropertyDescriptor(target, prop);
|
|
463
|
+
}
|
|
464
|
+
if (this.api && prop in this.api) {
|
|
465
|
+
const desc = Object.getOwnPropertyDescriptor(this.api, prop);
|
|
466
|
+
if (desc) {
|
|
467
|
+
return { ...desc, configurable: true };
|
|
468
|
+
}
|
|
469
|
+
}
|
|
470
|
+
return undefined;
|
|
471
|
+
}
|
|
623
472
|
});
|
|
624
|
-
|
|
625
|
-
console.warn("Could not redefine boundApi.shutdown: not configurable");
|
|
473
|
+
|
|
626
474
|
}
|
|
627
475
|
|
|
628
476
|
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
Object.defineProperty(boundApi, "addApi", {
|
|
632
|
-
value: this.addApi.bind(this),
|
|
633
|
-
writable: true,
|
|
634
|
-
configurable: true,
|
|
635
|
-
enumerable: false
|
|
636
|
-
});
|
|
637
|
-
} else if (this.config && this.config.debug) {
|
|
638
|
-
console.warn("Could not redefine boundApi.addApi: not configurable");
|
|
639
|
-
}
|
|
477
|
+
store.self = this.boundApi;
|
|
478
|
+
store.context = this.context || {};
|
|
640
479
|
|
|
641
480
|
|
|
642
|
-
|
|
643
|
-
if (
|
|
644
|
-
Object.
|
|
645
|
-
value: this.run.bind(this),
|
|
646
|
-
writable: true,
|
|
647
|
-
configurable: true,
|
|
648
|
-
enumerable: false
|
|
649
|
-
});
|
|
650
|
-
} else if (this.config && this.config.debug) {
|
|
651
|
-
console.warn("Could not redefine boundApi.run: not configurable");
|
|
481
|
+
|
|
482
|
+
if (this.reference && typeof this.reference === "object") {
|
|
483
|
+
Object.assign(this.boundApi, this.reference);
|
|
652
484
|
}
|
|
653
485
|
|
|
486
|
+
this.isLoaded = true;
|
|
487
|
+
|
|
488
|
+
return this.boundApi;
|
|
489
|
+
}
|
|
490
|
+
|
|
491
|
+
|
|
492
|
+
async reload(options = {}) {
|
|
493
|
+
const { keepInstanceID = false } = options;
|
|
494
|
+
|
|
495
|
+
|
|
654
496
|
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
writable: false,
|
|
660
|
-
configurable: true,
|
|
661
|
-
enumerable: false
|
|
497
|
+
if (!this.config?.dir) {
|
|
498
|
+
throw new SlothletError("INVALID_CONFIG_NOT_LOADED", {
|
|
499
|
+
operation: "reload",
|
|
500
|
+
validationError: true
|
|
662
501
|
});
|
|
663
502
|
}
|
|
664
503
|
|
|
665
504
|
|
|
666
|
-
const scopeDesc = Object.getOwnPropertyDescriptor(boundApi, "scope");
|
|
667
|
-
if (!scopeDesc || scopeDesc.configurable) {
|
|
668
|
-
Object.defineProperty(boundApi, "scope", {
|
|
669
|
-
value: this.scope.bind(this),
|
|
670
|
-
writable: true,
|
|
671
|
-
configurable: true,
|
|
672
|
-
enumerable: false
|
|
673
|
-
});
|
|
674
|
-
} else if (this.config && this.config.debug) {
|
|
675
|
-
console.warn("Could not redefine boundApi.scope: not configurable");
|
|
676
|
-
}
|
|
677
505
|
|
|
506
|
+
|
|
507
|
+
const operationHistory = this.handlers.apiManager?.state?.operationHistory ? [...this.handlers.apiManager.state.operationHistory] : [];
|
|
678
508
|
|
|
679
509
|
|
|
510
|
+
await this._clearModuleCaches();
|
|
680
511
|
|
|
681
512
|
|
|
682
513
|
|
|
514
|
+
|
|
515
|
+
|
|
516
|
+
const oldInstanceID = this.instanceID;
|
|
517
|
+
if (!keepInstanceID) {
|
|
518
|
+
this.instanceID = `${oldInstanceID}_reload_${Date.now()}`;
|
|
519
|
+
}
|
|
683
520
|
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
safeDefine(obj, key, value, enumerable = false) {
|
|
689
|
-
return safeDefine(obj, key, value, enumerable, this.config);
|
|
690
|
-
},
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
isLoaded() {
|
|
694
|
-
return this.loaded;
|
|
695
|
-
},
|
|
521
|
+
|
|
522
|
+
|
|
523
|
+
const savedMetadataState = this.handlers.metadata?.exportUserState?.();
|
|
696
524
|
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
},
|
|
525
|
+
|
|
526
|
+
|
|
527
|
+
const savedHooks = this.handlers.hookManager?.exportHooks?.();
|
|
701
528
|
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
return this.boundapi;
|
|
705
|
-
},
|
|
529
|
+
|
|
530
|
+
await this.load(this.config, this.instanceID);
|
|
706
531
|
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
if (this.
|
|
712
|
-
|
|
532
|
+
|
|
533
|
+
|
|
534
|
+
|
|
535
|
+
|
|
536
|
+
if (savedMetadataState && this.handlers.metadata) {
|
|
537
|
+
this.handlers.metadata.importUserState(savedMetadataState);
|
|
713
538
|
}
|
|
714
|
-
},
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
_getApiOwnership(apiPath) {
|
|
718
|
-
if (!this.config.enableModuleOwnership) return null;
|
|
719
|
-
return this._moduleOwnership.get(apiPath) || null;
|
|
720
|
-
},
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
_validateModuleOwnership(apiPath, moduleId, forceOverwrite) {
|
|
724
|
-
if (!this.config.enableModuleOwnership || !forceOverwrite) return false;
|
|
725
539
|
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
540
|
+
|
|
541
|
+
|
|
542
|
+
|
|
543
|
+
if (savedHooks?.length && this.handlers.hookManager) {
|
|
544
|
+
this.handlers.hookManager.importHooks(savedHooks);
|
|
730
545
|
}
|
|
731
546
|
|
|
732
547
|
|
|
733
|
-
|
|
734
|
-
|
|
548
|
+
|
|
549
|
+
|
|
550
|
+
for (const [, store] of this.contextManager.instances) {
|
|
551
|
+
if (store.parentInstanceID === oldInstanceID) {
|
|
552
|
+
store.parentInstanceID = this.instanceID;
|
|
553
|
+
}
|
|
735
554
|
}
|
|
736
555
|
|
|
737
556
|
|
|
738
|
-
|
|
739
|
-
|
|
557
|
+
|
|
558
|
+
if (oldInstanceID && oldInstanceID !== this.instanceID && this.contextManager.instances?.has(oldInstanceID)) {
|
|
559
|
+
this.contextManager.cleanup(oldInstanceID);
|
|
740
560
|
}
|
|
741
|
-
return false;
|
|
742
|
-
},
|
|
743
561
|
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
562
|
+
|
|
563
|
+
for (const operation of operationHistory) {
|
|
564
|
+
if (operation.type === "add") {
|
|
565
|
+
await this.handlers.apiManager.addApiComponent({
|
|
566
|
+
apiPath: operation.apiPath,
|
|
567
|
+
folderPath: operation.folderPath,
|
|
568
|
+
|
|
569
|
+
|
|
570
|
+
options: { ...(operation.options || {}), recordHistory: false },
|
|
571
|
+
moduleID: `replay_${this.helpers.utilities.generateId().substring(0, 8)}`
|
|
572
|
+
});
|
|
573
|
+
|
|
574
|
+
|
|
575
|
+
} else if (operation.type === "remove") {
|
|
576
|
+
|
|
577
|
+
|
|
578
|
+
const { parts } = this.handlers.apiManager.normalizeApiPath(operation.apiPath);
|
|
579
|
+
this.handlers.apiManager.deletePath(this.api, parts);
|
|
580
|
+
|
|
581
|
+
|
|
582
|
+
|
|
583
|
+
if (this.handlers.metadata) {
|
|
584
|
+
const rootSegment = operation.apiPath.split(".")[0];
|
|
585
|
+
this.handlers.metadata.removeUserMetadataByApiPath(rootSegment);
|
|
586
|
+
}
|
|
587
|
+
}
|
|
588
|
+
}
|
|
748
589
|
|
|
749
|
-
|
|
590
|
+
return this.boundApi;
|
|
591
|
+
}
|
|
750
592
|
|
|
751
593
|
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
594
|
+
async _clearModuleCaches() {
|
|
595
|
+
|
|
596
|
+
|
|
597
|
+
const targetDir = this.config.dir;
|
|
598
|
+
const { resolve } = await import("node:path");
|
|
599
|
+
const { createRequire } = await import("node:module");
|
|
600
|
+
const require = createRequire(import.meta.url);
|
|
601
|
+
const absoluteTargetDir = resolve(targetDir);
|
|
756
602
|
|
|
757
|
-
|
|
758
|
-
|
|
603
|
+
|
|
604
|
+
for (const key of Object.keys(require.cache)) {
|
|
605
|
+
if (key.startsWith(absoluteTargetDir)) {
|
|
606
|
+
delete require.cache[key];
|
|
607
|
+
}
|
|
759
608
|
}
|
|
760
609
|
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
return import("@cldmv/slothlet/runtime/async").then((asyncRuntime) => {
|
|
765
|
-
requestALS = asyncRuntime.requestALS;
|
|
766
|
-
const parentContext = requestALS.getStore() || {};
|
|
767
|
-
|
|
768
|
-
let mergedContext;
|
|
769
|
-
if (this.config.scope?.merge === "deep") {
|
|
770
|
-
const instanceContext = this.context || {};
|
|
771
|
-
let temp = this._deepMerge({}, instanceContext);
|
|
772
|
-
temp = this._deepMerge(temp, parentContext);
|
|
773
|
-
mergedContext = this._deepMerge(temp, contextData);
|
|
774
|
-
} else {
|
|
775
|
-
mergedContext = { ...parentContext, ...contextData };
|
|
776
|
-
}
|
|
777
|
-
|
|
778
|
-
return requestALS.run(mergedContext, () => callback(...args));
|
|
779
|
-
});
|
|
780
|
-
} else {
|
|
781
|
-
return import("@cldmv/slothlet/runtime/live").then((liveRuntime) => {
|
|
782
|
-
requestALS = liveRuntime.requestALS;
|
|
783
|
-
const parentContext = requestALS.getStore() || {};
|
|
784
|
-
|
|
785
|
-
let mergedContext;
|
|
786
|
-
if (this.config.scope?.merge === "deep") {
|
|
787
|
-
const instanceContext = this.context || {};
|
|
788
|
-
let temp = this._deepMerge({}, instanceContext);
|
|
789
|
-
temp = this._deepMerge(temp, parentContext);
|
|
790
|
-
mergedContext = this._deepMerge(temp, contextData);
|
|
791
|
-
} else {
|
|
792
|
-
mergedContext = { ...parentContext, ...contextData };
|
|
793
|
-
}
|
|
794
|
-
|
|
795
|
-
return requestALS.run(mergedContext, () => callback(...args));
|
|
796
|
-
});
|
|
797
|
-
}
|
|
798
|
-
},
|
|
610
|
+
|
|
611
|
+
|
|
612
|
+
}
|
|
799
613
|
|
|
800
614
|
|
|
801
|
-
|
|
802
|
-
if (
|
|
803
|
-
|
|
615
|
+
injectRuntimeMetadataFunctions(api) {
|
|
616
|
+
if (!api.slothlet?.metadata) {
|
|
617
|
+
return;
|
|
804
618
|
}
|
|
805
619
|
|
|
806
|
-
|
|
807
|
-
throw new TypeError("context must be an object.");
|
|
808
|
-
}
|
|
620
|
+
const metadataHandler = this.handlers.metadata;
|
|
809
621
|
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
622
|
+
|
|
623
|
+
api.slothlet.metadata.get = async function slothlet_metadata_get_runtime(path) {
|
|
624
|
+
return metadataHandler.get(path);
|
|
625
|
+
};
|
|
813
626
|
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
return import("./lib/runtime/runtime-asynclocalstorage.mjs").then((asyncRuntime) => {
|
|
818
|
-
requestALS = asyncRuntime.requestALS;
|
|
819
|
-
const parentContext = requestALS.getStore() || {};
|
|
820
|
-
|
|
821
|
-
let mergedContext;
|
|
822
|
-
if (this.config.scope?.merge === "deep") {
|
|
823
|
-
const instanceContext = this.context || {};
|
|
824
|
-
let temp = this._deepMerge({}, instanceContext);
|
|
825
|
-
temp = this._deepMerge(temp, parentContext);
|
|
826
|
-
mergedContext = this._deepMerge(temp, context);
|
|
827
|
-
} else {
|
|
828
|
-
mergedContext = { ...parentContext, ...context };
|
|
829
|
-
}
|
|
627
|
+
api.slothlet.metadata.self = function slothlet_metadata_self_runtime() {
|
|
628
|
+
return metadataHandler.self();
|
|
629
|
+
};
|
|
830
630
|
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
return import("./lib/runtime/runtime-livebindings.mjs").then((liveRuntime) => {
|
|
836
|
-
requestALS = liveRuntime.requestALS;
|
|
837
|
-
const parentContext = requestALS.getStore() || {};
|
|
838
|
-
|
|
839
|
-
let mergedContext;
|
|
840
|
-
if (this.config.scope?.merge === "deep") {
|
|
841
|
-
const instanceContext = this.context || {};
|
|
842
|
-
let temp = this._deepMerge({}, instanceContext);
|
|
843
|
-
temp = this._deepMerge(temp, parentContext);
|
|
844
|
-
mergedContext = this._deepMerge(temp, context);
|
|
845
|
-
} else {
|
|
846
|
-
mergedContext = { ...parentContext, ...context };
|
|
847
|
-
}
|
|
631
|
+
api.slothlet.metadata.caller = function slothlet_metadata_caller_runtime() {
|
|
632
|
+
return metadataHandler.caller();
|
|
633
|
+
};
|
|
634
|
+
}
|
|
848
635
|
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
636
|
+
|
|
637
|
+
async shutdown() {
|
|
638
|
+
if (!this.isLoaded) {
|
|
639
|
+
return;
|
|
852
640
|
}
|
|
853
|
-
},
|
|
854
641
|
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
642
|
+
|
|
643
|
+
disableEventEmitterPatching();
|
|
644
|
+
cleanupEventEmitterResources();
|
|
645
|
+
|
|
646
|
+
|
|
647
|
+
if (this.instanceID && this.contextManager) {
|
|
648
|
+
this.contextManager.cleanup(this.instanceID);
|
|
649
|
+
}
|
|
859
650
|
|
|
860
|
-
async shutdown() {
|
|
861
651
|
|
|
862
652
|
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
return;
|
|
653
|
+
|
|
654
|
+
if (this.handlers.ownership) {
|
|
655
|
+
this.handlers.ownership.clear();
|
|
867
656
|
}
|
|
868
|
-
this._shutdownInProgress = true;
|
|
869
|
-
try {
|
|
870
|
-
|
|
871
|
-
if (this.loaded) {
|
|
872
|
-
const TIMEOUT_MS = 5000;
|
|
873
|
-
let apiError, internalError;
|
|
874
|
-
if (typeof this._boundAPIShutdown === "function") {
|
|
875
|
-
try {
|
|
876
|
-
await Promise.race([
|
|
877
|
-
this._boundAPIShutdown.call(this.boundapi),
|
|
878
|
-
new Promise((_, reject) => setTimeout(() => reject(new Error("API shutdown timeout")), TIMEOUT_MS))
|
|
879
|
-
]);
|
|
880
|
-
} catch (err) {
|
|
881
|
-
apiError = err;
|
|
882
|
-
}
|
|
883
|
-
}
|
|
884
|
-
|
|
885
|
-
const disposeFn = this.boundapi && typeof this.boundapi.__dispose__ === "function" ? this.boundapi.__dispose__ : this._dispose;
|
|
886
|
-
if (typeof disposeFn === "function") {
|
|
887
|
-
try {
|
|
888
|
-
await disposeFn();
|
|
889
|
-
} catch (err) {
|
|
890
|
-
internalError = err;
|
|
891
|
-
}
|
|
892
|
-
}
|
|
893
|
-
this.loaded = false;
|
|
894
|
-
this.api = null;
|
|
895
|
-
this.boundapi = {};
|
|
896
|
-
this.context = {};
|
|
897
|
-
this.reference = {};
|
|
898
|
-
this._dispose = null;
|
|
899
|
-
this._boundAPIShutdown = null;
|
|
900
657
|
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
}
|
|
658
|
+
|
|
659
|
+
|
|
660
|
+
this.isLoaded = false;
|
|
661
|
+
}
|
|
906
662
|
|
|
907
|
-
|
|
663
|
+
|
|
664
|
+
debug(code, context = {}) {
|
|
665
|
+
if (this.debugLogger) {
|
|
666
|
+
this.debugLogger.log(code, context);
|
|
667
|
+
}
|
|
668
|
+
}
|
|
908
669
|
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
670
|
+
|
|
671
|
+
getAPI() {
|
|
672
|
+
if (!this.isLoaded) {
|
|
673
|
+
throw new SlothletError(
|
|
674
|
+
"INVALID_CONFIG_NOT_LOADED",
|
|
675
|
+
{
|
|
676
|
+
operation: "getAPI"
|
|
677
|
+
},
|
|
678
|
+
null,
|
|
679
|
+
{ validationError: true }
|
|
680
|
+
);
|
|
681
|
+
}
|
|
682
|
+
return this.boundApi;
|
|
683
|
+
}
|
|
913
684
|
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
}
|
|
685
|
+
|
|
686
|
+
getDiagnostics() {
|
|
687
|
+
return {
|
|
688
|
+
instanceID: this.instanceID,
|
|
689
|
+
isLoaded: this.isLoaded,
|
|
690
|
+
config: this.config,
|
|
691
|
+
context: this.contextManager?.getDiagnostics() || null,
|
|
692
|
+
ownership: this.handlers.ownership?.getDiagnostics() || null
|
|
693
|
+
};
|
|
694
|
+
}
|
|
925
695
|
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
this._shutdownInProgress = false;
|
|
696
|
+
|
|
697
|
+
getOwnership() {
|
|
698
|
+
if (!this.handlers.ownership) {
|
|
699
|
+
return null;
|
|
931
700
|
}
|
|
701
|
+
return this.handlers.ownership.getDiagnostics();
|
|
702
|
+
}
|
|
703
|
+
|
|
704
|
+
|
|
705
|
+
buildFinalAPI(userApi) {
|
|
706
|
+
return this.builders.apiBuilder.buildFinalAPI(userApi);
|
|
932
707
|
}
|
|
933
|
-
}
|
|
708
|
+
}
|
|
934
709
|
|
|
935
710
|
|
|
711
|
+
export async function slothlet(config) {
|
|
712
|
+
const instance = new Slothlet();
|
|
713
|
+
const api = await instance.load(config);
|
|
714
|
+
|
|
715
|
+
|
|
716
|
+
return api;
|
|
717
|
+
}
|
|
936
718
|
|
|
937
|
-
export { slothlet };
|
|
938
719
|
export default slothlet;
|
|
939
720
|
|
|
940
721
|
|