@nocobase/plugin-flow-engine 2.0.0-alpha.2
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/LICENSE +661 -0
- package/README.md +29 -0
- package/build.config.ts +22 -0
- package/client.d.ts +2 -0
- package/client.js +1 -0
- package/dist/client/index.d.ts +15 -0
- package/dist/client/index.js +10 -0
- package/dist/externalVersion.js +21 -0
- package/dist/index.d.ts +10 -0
- package/dist/index.js +48 -0
- package/dist/locale/en-US.json +61 -0
- package/dist/locale/index.d.ts +141 -0
- package/dist/locale/index.js +79 -0
- package/dist/locale/zh-CN.json +61 -0
- package/dist/node_modules/ses/LICENSE +201 -0
- package/dist/node_modules/ses/LICENSE-aura +16 -0
- package/dist/node_modules/ses/LICENSE-caja +13 -0
- package/dist/node_modules/ses/LICENSE-corejs +19 -0
- package/dist/node_modules/ses/LICENSE-v8 +9 -0
- package/dist/node_modules/ses/assert-shim.js +1 -0
- package/dist/node_modules/ses/compartment-shim.js +1 -0
- package/dist/node_modules/ses/console-shim.js +1 -0
- package/dist/node_modules/ses/dist/lockdown.cjs +13912 -0
- package/dist/node_modules/ses/dist/lockdown.umd.js +13912 -0
- package/dist/node_modules/ses/dist/lockdown.umd.min.js +1 -0
- package/dist/node_modules/ses/dist/ses-hermes.cjs +13912 -0
- package/dist/node_modules/ses/dist/ses.cjs +1 -0
- package/dist/node_modules/ses/dist/ses.umd.js +13912 -0
- package/dist/node_modules/ses/dist/ses.umd.min.js +1 -0
- package/dist/node_modules/ses/dist/types.d.cts +606 -0
- package/dist/node_modules/ses/index.js +18 -0
- package/dist/node_modules/ses/lockdown-shim.js +1 -0
- package/dist/node_modules/ses/lockdown.js +1 -0
- package/dist/node_modules/ses/package.json +1 -0
- package/dist/node_modules/ses/src/assert-shim.js +4 -0
- package/dist/node_modules/ses/src/assert-sloppy-mode.js +11 -0
- package/dist/node_modules/ses/src/cauterize-property.js +69 -0
- package/dist/node_modules/ses/src/commons.js +425 -0
- package/dist/node_modules/ses/src/compartment-evaluate.js +93 -0
- package/dist/node_modules/ses/src/compartment-shim.js +22 -0
- package/dist/node_modules/ses/src/compartment.js +477 -0
- package/dist/node_modules/ses/src/console-shim.js +50 -0
- package/dist/node_modules/ses/src/enable-property-overrides.js +211 -0
- package/dist/node_modules/ses/src/enablements.js +244 -0
- package/dist/node_modules/ses/src/error/assert.js +584 -0
- package/dist/node_modules/ses/src/error/console.js +541 -0
- package/dist/node_modules/ses/src/error/fatal-assert.js +54 -0
- package/dist/node_modules/ses/src/error/internal-types.js +98 -0
- package/dist/node_modules/ses/src/error/note-log-args.js +77 -0
- package/dist/node_modules/ses/src/error/stringify-utils.js +195 -0
- package/dist/node_modules/ses/src/error/tame-console.js +197 -0
- package/dist/node_modules/ses/src/error/tame-error-constructor.js +284 -0
- package/dist/node_modules/ses/src/error/tame-v8-error-constructor.js +386 -0
- package/dist/node_modules/ses/src/error/types.js +59 -0
- package/dist/node_modules/ses/src/error/unhandled-rejection.js +122 -0
- package/dist/node_modules/ses/src/eval-scope.js +89 -0
- package/dist/node_modules/ses/src/get-anonymous-intrinsics.js +181 -0
- package/dist/node_modules/ses/src/get-source-url.js +50 -0
- package/dist/node_modules/ses/src/global-object.js +175 -0
- package/dist/node_modules/ses/src/intrinsics.js +192 -0
- package/dist/node_modules/ses/src/lockdown-shim.js +37 -0
- package/dist/node_modules/ses/src/lockdown.js +558 -0
- package/dist/node_modules/ses/src/make-eval-function.js +28 -0
- package/dist/node_modules/ses/src/make-evaluate.js +110 -0
- package/dist/node_modules/ses/src/make-function-constructor.js +79 -0
- package/dist/node_modules/ses/src/make-hardener.js +275 -0
- package/dist/node_modules/ses/src/make-safe-evaluator.js +112 -0
- package/dist/node_modules/ses/src/module-instance.js +497 -0
- package/dist/node_modules/ses/src/module-link.js +159 -0
- package/dist/node_modules/ses/src/module-load.js +719 -0
- package/dist/node_modules/ses/src/module-proxy.js +200 -0
- package/dist/node_modules/ses/src/permits-intrinsics.js +291 -0
- package/dist/node_modules/ses/src/permits.js +1761 -0
- package/dist/node_modules/ses/src/reporting-types.d.ts +13 -0
- package/dist/node_modules/ses/src/reporting.js +105 -0
- package/dist/node_modules/ses/src/scope-constants.js +180 -0
- package/dist/node_modules/ses/src/shim-arraybuffer-transfer.js +85 -0
- package/dist/node_modules/ses/src/sloppy-globals-scope-terminator.js +61 -0
- package/dist/node_modules/ses/src/strict-scope-terminator.js +99 -0
- package/dist/node_modules/ses/src/tame-date-constructor.js +127 -0
- package/dist/node_modules/ses/src/tame-domains.js +41 -0
- package/dist/node_modules/ses/src/tame-faux-data-properties.js +210 -0
- package/dist/node_modules/ses/src/tame-function-constructors.js +140 -0
- package/dist/node_modules/ses/src/tame-function-tostring.js +50 -0
- package/dist/node_modules/ses/src/tame-harden.js +29 -0
- package/dist/node_modules/ses/src/tame-locale-methods.js +78 -0
- package/dist/node_modules/ses/src/tame-math-object.js +41 -0
- package/dist/node_modules/ses/src/tame-module-source.js +51 -0
- package/dist/node_modules/ses/src/tame-regenerator-runtime.js +29 -0
- package/dist/node_modules/ses/src/tame-regexp-constructor.js +65 -0
- package/dist/node_modules/ses/src/tame-symbol-constructor.js +64 -0
- package/dist/node_modules/ses/src/transforms.js +267 -0
- package/dist/node_modules/ses/tools.js +25 -0
- package/dist/node_modules/ses/types.d.ts +606 -0
- package/dist/server/actions/ui-schema-action.d.ts +27 -0
- package/dist/server/actions/ui-schema-action.js +118 -0
- package/dist/server/collections/flowModelTreePath.d.ts +11 -0
- package/dist/server/collections/flowModelTreePath.js +74 -0
- package/dist/server/collections/flowModels.d.ts +11 -0
- package/dist/server/collections/flowModels.js +57 -0
- package/dist/server/collections/flowsql.d.ts +10 -0
- package/dist/server/collections/flowsql.js +51 -0
- package/dist/server/dao/ui_schema_node_dao.d.ts +26 -0
- package/dist/server/dao/ui_schema_node_dao.js +24 -0
- package/dist/server/helper.d.ts +8 -0
- package/dist/server/helper.js +9 -0
- package/dist/server/index.d.ts +9 -0
- package/dist/server/index.js +42 -0
- package/dist/server/model.d.ts +12 -0
- package/dist/server/model.js +38 -0
- package/dist/server/plugin.d.ts +26 -0
- package/dist/server/plugin.js +270 -0
- package/dist/server/repository.d.ts +116 -0
- package/dist/server/repository.js +1209 -0
- package/dist/server/server.d.ts +16 -0
- package/dist/server/server.js +198 -0
- package/dist/server/template/contexts.d.ts +73 -0
- package/dist/server/template/contexts.js +233 -0
- package/dist/server/template/resolver.d.ts +30 -0
- package/dist/server/template/resolver.js +225 -0
- package/dist/server/variables/registry.d.ts +42 -0
- package/dist/server/variables/registry.js +299 -0
- package/package.json +28 -0
- package/server.d.ts +2 -0
- package/server.js +1 -0
|
@@ -0,0 +1,497 @@
|
|
|
1
|
+
/** @import {ModuleExportsNamespace} from '../types.js' */
|
|
2
|
+
|
|
3
|
+
import { assert } from './error/assert.js';
|
|
4
|
+
import { getDeferredExports } from './module-proxy.js';
|
|
5
|
+
import {
|
|
6
|
+
ReferenceError,
|
|
7
|
+
SyntaxError,
|
|
8
|
+
TypeError,
|
|
9
|
+
arrayForEach,
|
|
10
|
+
arrayIncludes,
|
|
11
|
+
arrayPush,
|
|
12
|
+
arraySome,
|
|
13
|
+
arraySort,
|
|
14
|
+
create,
|
|
15
|
+
defineProperty,
|
|
16
|
+
entries,
|
|
17
|
+
freeze,
|
|
18
|
+
isArray,
|
|
19
|
+
keys,
|
|
20
|
+
mapGet,
|
|
21
|
+
weakmapGet,
|
|
22
|
+
reflectHas,
|
|
23
|
+
assign,
|
|
24
|
+
} from './commons.js';
|
|
25
|
+
import { compartmentEvaluate } from './compartment-evaluate.js';
|
|
26
|
+
|
|
27
|
+
const { quote: q } = assert;
|
|
28
|
+
|
|
29
|
+
export const makeVirtualModuleInstance = (
|
|
30
|
+
compartmentPrivateFields,
|
|
31
|
+
moduleSource,
|
|
32
|
+
compartment,
|
|
33
|
+
moduleAliases,
|
|
34
|
+
moduleSpecifier,
|
|
35
|
+
resolvedImports,
|
|
36
|
+
) => {
|
|
37
|
+
const { exportsProxy, exportsTarget, activate } = getDeferredExports(
|
|
38
|
+
compartment,
|
|
39
|
+
weakmapGet(compartmentPrivateFields, compartment),
|
|
40
|
+
moduleAliases,
|
|
41
|
+
moduleSpecifier,
|
|
42
|
+
);
|
|
43
|
+
|
|
44
|
+
const notifiers = create(null);
|
|
45
|
+
|
|
46
|
+
if (moduleSource.exports) {
|
|
47
|
+
if (
|
|
48
|
+
!isArray(moduleSource.exports) ||
|
|
49
|
+
arraySome(moduleSource.exports, name => typeof name !== 'string')
|
|
50
|
+
) {
|
|
51
|
+
throw TypeError(
|
|
52
|
+
`SES virtual module source "exports" property must be an array of strings for module ${moduleSpecifier}`,
|
|
53
|
+
);
|
|
54
|
+
}
|
|
55
|
+
arrayForEach(moduleSource.exports, name => {
|
|
56
|
+
let value = exportsTarget[name];
|
|
57
|
+
const updaters = [];
|
|
58
|
+
|
|
59
|
+
const get = () => value;
|
|
60
|
+
|
|
61
|
+
const set = newValue => {
|
|
62
|
+
value = newValue;
|
|
63
|
+
for (const updater of updaters) {
|
|
64
|
+
updater(newValue);
|
|
65
|
+
}
|
|
66
|
+
};
|
|
67
|
+
|
|
68
|
+
defineProperty(exportsTarget, name, {
|
|
69
|
+
get,
|
|
70
|
+
set,
|
|
71
|
+
enumerable: true,
|
|
72
|
+
configurable: false,
|
|
73
|
+
});
|
|
74
|
+
|
|
75
|
+
notifiers[name] = update => {
|
|
76
|
+
arrayPush(updaters, update);
|
|
77
|
+
update(value);
|
|
78
|
+
};
|
|
79
|
+
});
|
|
80
|
+
// This is enough to support import * from cjs - the '*' field doesn't need to be in exports nor exportsTarget because import will only ever access it via notifiers
|
|
81
|
+
notifiers['*'] = update => {
|
|
82
|
+
update(exportsTarget);
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
const localState = {
|
|
87
|
+
activated: false,
|
|
88
|
+
};
|
|
89
|
+
return freeze({
|
|
90
|
+
notifiers,
|
|
91
|
+
exportsProxy,
|
|
92
|
+
execute() {
|
|
93
|
+
if (reflectHas(localState, 'errorFromExecute')) {
|
|
94
|
+
throw localState.errorFromExecute;
|
|
95
|
+
}
|
|
96
|
+
if (!localState.activated) {
|
|
97
|
+
activate();
|
|
98
|
+
localState.activated = true;
|
|
99
|
+
try {
|
|
100
|
+
// eslint-disable-next-line @endo/no-polymorphic-call
|
|
101
|
+
moduleSource.execute(exportsTarget, compartment, resolvedImports);
|
|
102
|
+
} catch (err) {
|
|
103
|
+
localState.errorFromExecute = err;
|
|
104
|
+
throw err;
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
},
|
|
108
|
+
});
|
|
109
|
+
};
|
|
110
|
+
|
|
111
|
+
// `makeModuleInstance` takes a module's compartment record, the live import
|
|
112
|
+
// namespace, and a global object; and produces a module instance.
|
|
113
|
+
// The module instance carries the proxied module exports namespace (the
|
|
114
|
+
// "exports"), notifiers to update the module's internal import namespace, and
|
|
115
|
+
// an idempotent execute function.
|
|
116
|
+
// The module exports namespace is a proxy to the proxied exports namespace
|
|
117
|
+
// that the execution of the module instance populates.
|
|
118
|
+
export const makeModuleInstance = (
|
|
119
|
+
privateFields,
|
|
120
|
+
moduleAliases,
|
|
121
|
+
moduleRecord,
|
|
122
|
+
importedInstances,
|
|
123
|
+
) => {
|
|
124
|
+
const {
|
|
125
|
+
compartment,
|
|
126
|
+
moduleSpecifier,
|
|
127
|
+
moduleSource,
|
|
128
|
+
importMeta: moduleRecordMeta,
|
|
129
|
+
} = moduleRecord;
|
|
130
|
+
const {
|
|
131
|
+
reexports: exportAlls = [],
|
|
132
|
+
__syncModuleProgram__: functorSource,
|
|
133
|
+
__fixedExportMap__: fixedExportMap = {},
|
|
134
|
+
__liveExportMap__: liveExportMap = {},
|
|
135
|
+
__reexportMap__: reexportMap = {},
|
|
136
|
+
__needsImport__: needsImport = false,
|
|
137
|
+
__needsImportMeta__: needsImportMeta = false,
|
|
138
|
+
__syncModuleFunctor__,
|
|
139
|
+
} = moduleSource;
|
|
140
|
+
|
|
141
|
+
const compartmentFields = weakmapGet(privateFields, compartment);
|
|
142
|
+
|
|
143
|
+
const { __shimTransforms__, resolveHook, importMetaHook, compartmentImport } =
|
|
144
|
+
compartmentFields;
|
|
145
|
+
|
|
146
|
+
const { exportsProxy, exportsTarget, activate } = getDeferredExports(
|
|
147
|
+
compartment,
|
|
148
|
+
compartmentFields,
|
|
149
|
+
moduleAliases,
|
|
150
|
+
moduleSpecifier,
|
|
151
|
+
);
|
|
152
|
+
|
|
153
|
+
// {_exportName_: getter} module exports namespace
|
|
154
|
+
// object (eventually proxied).
|
|
155
|
+
const exportsProps = create(null);
|
|
156
|
+
|
|
157
|
+
// {_localName_: accessor} proxy traps for moduleLexicals and live bindings.
|
|
158
|
+
// The moduleLexicals object is frozen and the corresponding properties of
|
|
159
|
+
// moduleLexicals must be immutable, so we copy the descriptors.
|
|
160
|
+
const moduleLexicals = create(null);
|
|
161
|
+
|
|
162
|
+
// {_localName_: init(initValue) -> initValue} used by the
|
|
163
|
+
// rewritten code to initialize exported fixed bindings.
|
|
164
|
+
const onceVar = create(null);
|
|
165
|
+
|
|
166
|
+
// {_localName_: update(newValue)} used by the rewritten code to
|
|
167
|
+
// both initialize and update live bindings.
|
|
168
|
+
const liveVar = create(null);
|
|
169
|
+
|
|
170
|
+
const importMeta = create(null);
|
|
171
|
+
if (moduleRecordMeta) {
|
|
172
|
+
assign(importMeta, moduleRecordMeta);
|
|
173
|
+
}
|
|
174
|
+
if (needsImportMeta && importMetaHook) {
|
|
175
|
+
importMetaHook(moduleSpecifier, importMeta);
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
/** @type {(fullSpecifier: string) => Promise<ModuleExportsNamespace>} */
|
|
179
|
+
let dynamicImport;
|
|
180
|
+
if (needsImport) {
|
|
181
|
+
/** @param {string} importSpecifier */
|
|
182
|
+
dynamicImport = async importSpecifier =>
|
|
183
|
+
compartmentImport(resolveHook(importSpecifier, moduleSpecifier));
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
// {_localName_: [{get, set, notify}]} used to merge all the export updaters.
|
|
187
|
+
const localGetNotify = create(null);
|
|
188
|
+
|
|
189
|
+
// {[importName: string]: notify(update(newValue))} Used by code that imports
|
|
190
|
+
// one of this module's exports, so that their update function will
|
|
191
|
+
// be notified when this binding is initialized or updated.
|
|
192
|
+
const notifiers = create(null);
|
|
193
|
+
|
|
194
|
+
arrayForEach(entries(fixedExportMap), ([fixedExportName, [localName]]) => {
|
|
195
|
+
let fixedGetNotify = localGetNotify[localName];
|
|
196
|
+
if (!fixedGetNotify) {
|
|
197
|
+
// fixed binding state
|
|
198
|
+
let value;
|
|
199
|
+
let tdz = true;
|
|
200
|
+
/** @type {null | Array<(value: any) => void>} */
|
|
201
|
+
let optUpdaters = [];
|
|
202
|
+
|
|
203
|
+
// tdz sensitive getter
|
|
204
|
+
const get = () => {
|
|
205
|
+
if (tdz) {
|
|
206
|
+
throw ReferenceError(`binding ${q(localName)} not yet initialized`);
|
|
207
|
+
}
|
|
208
|
+
return value;
|
|
209
|
+
};
|
|
210
|
+
|
|
211
|
+
// leave tdz once
|
|
212
|
+
const init = freeze(initValue => {
|
|
213
|
+
// init with initValue of a declared const binding, and return
|
|
214
|
+
// it.
|
|
215
|
+
if (!tdz) {
|
|
216
|
+
throw TypeError(
|
|
217
|
+
`Internal: binding ${q(localName)} already initialized`,
|
|
218
|
+
);
|
|
219
|
+
}
|
|
220
|
+
value = initValue;
|
|
221
|
+
const updaters = optUpdaters;
|
|
222
|
+
optUpdaters = null;
|
|
223
|
+
tdz = false;
|
|
224
|
+
for (const updater of updaters || []) {
|
|
225
|
+
updater(initValue);
|
|
226
|
+
}
|
|
227
|
+
return initValue;
|
|
228
|
+
});
|
|
229
|
+
|
|
230
|
+
// If still tdz, register update for notification later.
|
|
231
|
+
// Otherwise, update now.
|
|
232
|
+
const notify = updater => {
|
|
233
|
+
if (updater === init) {
|
|
234
|
+
// Prevent recursion.
|
|
235
|
+
return;
|
|
236
|
+
}
|
|
237
|
+
if (tdz) {
|
|
238
|
+
arrayPush(optUpdaters || [], updater);
|
|
239
|
+
} else {
|
|
240
|
+
updater(value);
|
|
241
|
+
}
|
|
242
|
+
};
|
|
243
|
+
|
|
244
|
+
// Need these for additional exports of the local variable.
|
|
245
|
+
fixedGetNotify = {
|
|
246
|
+
get,
|
|
247
|
+
notify,
|
|
248
|
+
};
|
|
249
|
+
localGetNotify[localName] = fixedGetNotify;
|
|
250
|
+
onceVar[localName] = init;
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
exportsProps[fixedExportName] = {
|
|
254
|
+
get: fixedGetNotify.get,
|
|
255
|
+
set: undefined,
|
|
256
|
+
enumerable: true,
|
|
257
|
+
configurable: false,
|
|
258
|
+
};
|
|
259
|
+
|
|
260
|
+
notifiers[fixedExportName] = fixedGetNotify.notify;
|
|
261
|
+
});
|
|
262
|
+
|
|
263
|
+
arrayForEach(
|
|
264
|
+
entries(liveExportMap),
|
|
265
|
+
([liveExportName, [localName, setProxyTrap]]) => {
|
|
266
|
+
let liveGetNotify = localGetNotify[localName];
|
|
267
|
+
if (!liveGetNotify) {
|
|
268
|
+
// live binding state
|
|
269
|
+
let value;
|
|
270
|
+
let tdz = true;
|
|
271
|
+
const updaters = [];
|
|
272
|
+
|
|
273
|
+
// tdz sensitive getter
|
|
274
|
+
const get = () => {
|
|
275
|
+
if (tdz) {
|
|
276
|
+
throw ReferenceError(
|
|
277
|
+
`binding ${q(liveExportName)} not yet initialized`,
|
|
278
|
+
);
|
|
279
|
+
}
|
|
280
|
+
return value;
|
|
281
|
+
};
|
|
282
|
+
|
|
283
|
+
// This must be usable locally for the translation of initializing
|
|
284
|
+
// a declared local live binding variable.
|
|
285
|
+
//
|
|
286
|
+
// For reexported variable, this is also an update function to
|
|
287
|
+
// register for notification with the downstream import, which we
|
|
288
|
+
// must assume to be live. Thus, it can be called independent of
|
|
289
|
+
// tdz but always leaves tdz. Such reexporting creates a tree of
|
|
290
|
+
// bindings. This lets the tree be hooked up even if the imported
|
|
291
|
+
// module instance isn't initialized yet, as may happen in cycles.
|
|
292
|
+
const update = freeze(newValue => {
|
|
293
|
+
value = newValue;
|
|
294
|
+
tdz = false;
|
|
295
|
+
for (const updater of updaters) {
|
|
296
|
+
updater(newValue);
|
|
297
|
+
}
|
|
298
|
+
});
|
|
299
|
+
|
|
300
|
+
// tdz sensitive setter
|
|
301
|
+
const set = newValue => {
|
|
302
|
+
if (tdz) {
|
|
303
|
+
throw ReferenceError(`binding ${q(localName)} not yet initialized`);
|
|
304
|
+
}
|
|
305
|
+
value = newValue;
|
|
306
|
+
for (const updater of updaters) {
|
|
307
|
+
updater(newValue);
|
|
308
|
+
}
|
|
309
|
+
};
|
|
310
|
+
|
|
311
|
+
// Always register the updater function.
|
|
312
|
+
// If not in tdz, also update now.
|
|
313
|
+
const notify = updater => {
|
|
314
|
+
if (updater === update) {
|
|
315
|
+
// Prevent recursion.
|
|
316
|
+
return;
|
|
317
|
+
}
|
|
318
|
+
arrayPush(updaters, updater);
|
|
319
|
+
if (!tdz) {
|
|
320
|
+
updater(value);
|
|
321
|
+
}
|
|
322
|
+
};
|
|
323
|
+
|
|
324
|
+
liveGetNotify = {
|
|
325
|
+
get,
|
|
326
|
+
notify,
|
|
327
|
+
};
|
|
328
|
+
|
|
329
|
+
localGetNotify[localName] = liveGetNotify;
|
|
330
|
+
if (setProxyTrap) {
|
|
331
|
+
defineProperty(moduleLexicals, localName, {
|
|
332
|
+
get,
|
|
333
|
+
set,
|
|
334
|
+
enumerable: true,
|
|
335
|
+
configurable: false,
|
|
336
|
+
});
|
|
337
|
+
}
|
|
338
|
+
liveVar[localName] = update;
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
exportsProps[liveExportName] = {
|
|
342
|
+
get: liveGetNotify.get,
|
|
343
|
+
set: undefined,
|
|
344
|
+
enumerable: true,
|
|
345
|
+
configurable: false,
|
|
346
|
+
};
|
|
347
|
+
|
|
348
|
+
notifiers[liveExportName] = liveGetNotify.notify;
|
|
349
|
+
},
|
|
350
|
+
);
|
|
351
|
+
|
|
352
|
+
const notifyStar = update => {
|
|
353
|
+
update(exportsTarget);
|
|
354
|
+
};
|
|
355
|
+
notifiers['*'] = notifyStar;
|
|
356
|
+
|
|
357
|
+
// Per the calling convention for the moduleFunctor generated from
|
|
358
|
+
// an ESM, the `imports` function gets called once up front
|
|
359
|
+
// to populate or arrange the population of imports and reexports.
|
|
360
|
+
// The generated code produces an `updateRecord`: the means for
|
|
361
|
+
// the linker to update the imports and exports of the module.
|
|
362
|
+
// The updateRecord must conform to moduleAnalysis.imports
|
|
363
|
+
// updateRecord = Map<specifier, importUpdaters>
|
|
364
|
+
// importUpdaters = Map<importName, [update(newValue)*]>
|
|
365
|
+
function imports(updateRecord) {
|
|
366
|
+
// By the time imports is called, the importedInstances should already be
|
|
367
|
+
// initialized with module instances that satisfy
|
|
368
|
+
// imports.
|
|
369
|
+
// importedInstances = Map[_specifier_, { notifiers, module, execute }]
|
|
370
|
+
// notifiers = { [importName: string]: notify(update(newValue))}
|
|
371
|
+
|
|
372
|
+
// export * cannot export default.
|
|
373
|
+
const candidateAll = create(null);
|
|
374
|
+
candidateAll.default = false;
|
|
375
|
+
for (const [specifier, importUpdaters] of updateRecord) {
|
|
376
|
+
const instance = mapGet(importedInstances, specifier);
|
|
377
|
+
// The module instance object is an internal literal, does not bind this,
|
|
378
|
+
// and never revealed outside the SES shim.
|
|
379
|
+
// There are two instantiation sites for instances and they are both in
|
|
380
|
+
// this module.
|
|
381
|
+
// eslint-disable-next-line @endo/no-polymorphic-call
|
|
382
|
+
instance.execute(); // bottom up cycle tolerant
|
|
383
|
+
const { notifiers: importNotifiers } = instance;
|
|
384
|
+
for (const [importName, updaters] of importUpdaters) {
|
|
385
|
+
const importNotify = importNotifiers[importName];
|
|
386
|
+
if (!importNotify) {
|
|
387
|
+
throw SyntaxError(
|
|
388
|
+
`The requested module '${specifier}' does not provide an export named '${importName}'`,
|
|
389
|
+
);
|
|
390
|
+
}
|
|
391
|
+
for (const updater of updaters) {
|
|
392
|
+
importNotify(updater);
|
|
393
|
+
}
|
|
394
|
+
}
|
|
395
|
+
if (arrayIncludes(exportAlls, specifier)) {
|
|
396
|
+
// Make all these imports candidates.
|
|
397
|
+
// Note names don't change in reexporting all
|
|
398
|
+
for (const [importAndExportName, importNotify] of entries(
|
|
399
|
+
importNotifiers,
|
|
400
|
+
)) {
|
|
401
|
+
if (candidateAll[importAndExportName] === undefined) {
|
|
402
|
+
candidateAll[importAndExportName] = importNotify;
|
|
403
|
+
} else {
|
|
404
|
+
// Already a candidate: remove ambiguity.
|
|
405
|
+
candidateAll[importAndExportName] = false;
|
|
406
|
+
}
|
|
407
|
+
}
|
|
408
|
+
}
|
|
409
|
+
if (reexportMap[specifier]) {
|
|
410
|
+
// Make named reexports candidates too.
|
|
411
|
+
for (const [localName, exportedName] of reexportMap[specifier]) {
|
|
412
|
+
candidateAll[exportedName] = importNotifiers[localName];
|
|
413
|
+
}
|
|
414
|
+
}
|
|
415
|
+
}
|
|
416
|
+
|
|
417
|
+
for (const [exportName, notify] of entries(candidateAll)) {
|
|
418
|
+
if (!notifiers[exportName] && notify !== false) {
|
|
419
|
+
notifiers[exportName] = notify;
|
|
420
|
+
|
|
421
|
+
// exported live binding state
|
|
422
|
+
let value;
|
|
423
|
+
const update = newValue => (value = newValue);
|
|
424
|
+
notify(update);
|
|
425
|
+
exportsProps[exportName] = {
|
|
426
|
+
get() {
|
|
427
|
+
return value;
|
|
428
|
+
},
|
|
429
|
+
set: undefined,
|
|
430
|
+
enumerable: true,
|
|
431
|
+
configurable: false,
|
|
432
|
+
};
|
|
433
|
+
}
|
|
434
|
+
}
|
|
435
|
+
|
|
436
|
+
// Sort the module exports namespace as per spec.
|
|
437
|
+
// The module exports namespace will be wrapped in a module namespace
|
|
438
|
+
// exports proxy which will serve as a "module exports namespace exotic
|
|
439
|
+
// object".
|
|
440
|
+
// Sorting properties is not generally reliable because some properties may
|
|
441
|
+
// be symbols, and symbols do not have an inherent relative order, but
|
|
442
|
+
// since all properties of the exports namespace must be keyed by a string
|
|
443
|
+
// and the string must correspond to a valid identifier, sorting these
|
|
444
|
+
// properties works for this specific case.
|
|
445
|
+
arrayForEach(arraySort(keys(exportsProps)), k =>
|
|
446
|
+
defineProperty(exportsTarget, k, exportsProps[k]),
|
|
447
|
+
);
|
|
448
|
+
|
|
449
|
+
freeze(exportsTarget);
|
|
450
|
+
activate();
|
|
451
|
+
}
|
|
452
|
+
|
|
453
|
+
let optFunctor;
|
|
454
|
+
if (__syncModuleFunctor__ !== undefined) {
|
|
455
|
+
optFunctor = __syncModuleFunctor__;
|
|
456
|
+
} else {
|
|
457
|
+
optFunctor = compartmentEvaluate(compartmentFields, functorSource, {
|
|
458
|
+
globalObject: compartment.globalThis,
|
|
459
|
+
transforms: __shimTransforms__,
|
|
460
|
+
__moduleShimLexicals__: moduleLexicals,
|
|
461
|
+
});
|
|
462
|
+
}
|
|
463
|
+
let didThrow = false;
|
|
464
|
+
let thrownError;
|
|
465
|
+
function execute() {
|
|
466
|
+
if (optFunctor) {
|
|
467
|
+
// uninitialized
|
|
468
|
+
const functor = optFunctor;
|
|
469
|
+
optFunctor = null;
|
|
470
|
+
// initializing - call with `this` of `undefined`.
|
|
471
|
+
try {
|
|
472
|
+
functor(
|
|
473
|
+
freeze({
|
|
474
|
+
imports: freeze(imports),
|
|
475
|
+
onceVar: freeze(onceVar),
|
|
476
|
+
liveVar: freeze(liveVar),
|
|
477
|
+
import: dynamicImport,
|
|
478
|
+
importMeta,
|
|
479
|
+
}),
|
|
480
|
+
);
|
|
481
|
+
} catch (e) {
|
|
482
|
+
didThrow = true;
|
|
483
|
+
thrownError = e;
|
|
484
|
+
}
|
|
485
|
+
// initialized
|
|
486
|
+
}
|
|
487
|
+
if (didThrow) {
|
|
488
|
+
throw thrownError;
|
|
489
|
+
}
|
|
490
|
+
}
|
|
491
|
+
|
|
492
|
+
return freeze({
|
|
493
|
+
notifiers,
|
|
494
|
+
exportsProxy,
|
|
495
|
+
execute,
|
|
496
|
+
});
|
|
497
|
+
};
|
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
/* eslint-disable no-underscore-dangle */
|
|
2
|
+
|
|
3
|
+
import { assert } from './error/assert.js';
|
|
4
|
+
import {
|
|
5
|
+
makeModuleInstance,
|
|
6
|
+
makeVirtualModuleInstance,
|
|
7
|
+
} from './module-instance.js';
|
|
8
|
+
import {
|
|
9
|
+
Map,
|
|
10
|
+
ReferenceError,
|
|
11
|
+
TypeError,
|
|
12
|
+
entries,
|
|
13
|
+
isArray,
|
|
14
|
+
isPrimitive,
|
|
15
|
+
mapGet,
|
|
16
|
+
mapHas,
|
|
17
|
+
mapSet,
|
|
18
|
+
weakmapGet,
|
|
19
|
+
} from './commons.js';
|
|
20
|
+
|
|
21
|
+
const { Fail, quote: q } = assert;
|
|
22
|
+
|
|
23
|
+
// `link` creates `ModuleInstances` and `ModuleNamespaces` for a module and its
|
|
24
|
+
// transitive dependencies and connects their imports and exports.
|
|
25
|
+
// After linking, the resulting working set is ready to be executed.
|
|
26
|
+
// The linker only concerns itself with module namespaces that are objects with
|
|
27
|
+
// property descriptors for their exports, which the Compartment proxies with
|
|
28
|
+
// the actual `ModuleNamespace`.
|
|
29
|
+
export const link = (
|
|
30
|
+
compartmentPrivateFields,
|
|
31
|
+
moduleAliases,
|
|
32
|
+
compartment,
|
|
33
|
+
moduleSpecifier,
|
|
34
|
+
) => {
|
|
35
|
+
const { name: compartmentName, moduleRecords } = weakmapGet(
|
|
36
|
+
compartmentPrivateFields,
|
|
37
|
+
compartment,
|
|
38
|
+
);
|
|
39
|
+
|
|
40
|
+
const moduleRecord = mapGet(moduleRecords, moduleSpecifier);
|
|
41
|
+
if (moduleRecord === undefined) {
|
|
42
|
+
throw ReferenceError(
|
|
43
|
+
`Missing link to module ${q(moduleSpecifier)} from compartment ${q(
|
|
44
|
+
compartmentName,
|
|
45
|
+
)}`,
|
|
46
|
+
);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
// Mutual recursion so there's no confusion about which
|
|
50
|
+
// compartment is in context: the module record may be in another
|
|
51
|
+
// compartment, denoted by moduleRecord.compartment.
|
|
52
|
+
// eslint-disable-next-line no-use-before-define
|
|
53
|
+
return instantiate(compartmentPrivateFields, moduleAliases, moduleRecord);
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
function mayBePrecompiledModuleSource(moduleSource) {
|
|
57
|
+
return typeof moduleSource.__syncModuleProgram__ === 'string';
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
function validatePrecompiledModuleSource(moduleSource, moduleSpecifier) {
|
|
61
|
+
const { __fixedExportMap__, __liveExportMap__ } = moduleSource;
|
|
62
|
+
!isPrimitive(__fixedExportMap__) ||
|
|
63
|
+
Fail`Property '__fixedExportMap__' of a precompiled module source must be an object, got ${q(
|
|
64
|
+
__fixedExportMap__,
|
|
65
|
+
)}, for module ${q(moduleSpecifier)}`;
|
|
66
|
+
!isPrimitive(__liveExportMap__) ||
|
|
67
|
+
Fail`Property '__liveExportMap__' of a precompiled module source must be an object, got ${q(
|
|
68
|
+
__liveExportMap__,
|
|
69
|
+
)}, for module ${q(moduleSpecifier)}`;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
function mayBeVirtualModuleSource(moduleSource) {
|
|
73
|
+
return typeof moduleSource.execute === 'function';
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
function validateVirtualModuleSource(moduleSource, moduleSpecifier) {
|
|
77
|
+
const { exports } = moduleSource;
|
|
78
|
+
isArray(exports) ||
|
|
79
|
+
Fail`Invalid module source: 'exports' of a virtual module source must be an array, got ${q(
|
|
80
|
+
exports,
|
|
81
|
+
)}, for module ${q(moduleSpecifier)}`;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
function validateModuleSource(moduleSource, moduleSpecifier) {
|
|
85
|
+
!isPrimitive(moduleSource) ||
|
|
86
|
+
Fail`Invalid module source: must be of type object, got ${q(
|
|
87
|
+
moduleSource,
|
|
88
|
+
)}, for module ${q(moduleSpecifier)}`;
|
|
89
|
+
const { imports, exports, reexports = [] } = moduleSource;
|
|
90
|
+
isArray(imports) ||
|
|
91
|
+
Fail`Invalid module source: 'imports' must be an array, got ${q(
|
|
92
|
+
imports,
|
|
93
|
+
)}, for module ${q(moduleSpecifier)}`;
|
|
94
|
+
isArray(exports) ||
|
|
95
|
+
Fail`Invalid module source: 'exports' must be an array, got ${q(
|
|
96
|
+
exports,
|
|
97
|
+
)}, for module ${q(moduleSpecifier)}`;
|
|
98
|
+
isArray(reexports) ||
|
|
99
|
+
Fail`Invalid module source: 'reexports' must be an array if present, got ${q(
|
|
100
|
+
reexports,
|
|
101
|
+
)}, for module ${q(moduleSpecifier)}`;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
export const instantiate = (
|
|
105
|
+
compartmentPrivateFields,
|
|
106
|
+
moduleAliases,
|
|
107
|
+
moduleRecord,
|
|
108
|
+
) => {
|
|
109
|
+
const { compartment, moduleSpecifier, resolvedImports, moduleSource } =
|
|
110
|
+
moduleRecord;
|
|
111
|
+
const { instances } = weakmapGet(compartmentPrivateFields, compartment);
|
|
112
|
+
|
|
113
|
+
// Memoize.
|
|
114
|
+
if (mapHas(instances, moduleSpecifier)) {
|
|
115
|
+
return mapGet(instances, moduleSpecifier);
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
validateModuleSource(moduleSource, moduleSpecifier);
|
|
119
|
+
|
|
120
|
+
const importedInstances = new Map();
|
|
121
|
+
let moduleInstance;
|
|
122
|
+
if (mayBePrecompiledModuleSource(moduleSource)) {
|
|
123
|
+
validatePrecompiledModuleSource(moduleSource, moduleSpecifier);
|
|
124
|
+
moduleInstance = makeModuleInstance(
|
|
125
|
+
compartmentPrivateFields,
|
|
126
|
+
moduleAliases,
|
|
127
|
+
moduleRecord,
|
|
128
|
+
importedInstances,
|
|
129
|
+
);
|
|
130
|
+
} else if (mayBeVirtualModuleSource(moduleSource)) {
|
|
131
|
+
validateVirtualModuleSource(moduleSource, moduleSpecifier);
|
|
132
|
+
moduleInstance = makeVirtualModuleInstance(
|
|
133
|
+
compartmentPrivateFields,
|
|
134
|
+
moduleSource,
|
|
135
|
+
compartment,
|
|
136
|
+
moduleAliases,
|
|
137
|
+
moduleSpecifier,
|
|
138
|
+
resolvedImports,
|
|
139
|
+
);
|
|
140
|
+
} else {
|
|
141
|
+
throw TypeError(`Invalid module source, got ${q(moduleSource)}`);
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
// Memoize.
|
|
145
|
+
mapSet(instances, moduleSpecifier, moduleInstance);
|
|
146
|
+
|
|
147
|
+
// Link dependency modules.
|
|
148
|
+
for (const [importSpecifier, resolvedSpecifier] of entries(resolvedImports)) {
|
|
149
|
+
const importedInstance = link(
|
|
150
|
+
compartmentPrivateFields,
|
|
151
|
+
moduleAliases,
|
|
152
|
+
compartment,
|
|
153
|
+
resolvedSpecifier,
|
|
154
|
+
);
|
|
155
|
+
mapSet(importedInstances, importSpecifier, importedInstance);
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
return moduleInstance;
|
|
159
|
+
};
|