@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.
Files changed (125) hide show
  1. package/LICENSE +661 -0
  2. package/README.md +29 -0
  3. package/build.config.ts +22 -0
  4. package/client.d.ts +2 -0
  5. package/client.js +1 -0
  6. package/dist/client/index.d.ts +15 -0
  7. package/dist/client/index.js +10 -0
  8. package/dist/externalVersion.js +21 -0
  9. package/dist/index.d.ts +10 -0
  10. package/dist/index.js +48 -0
  11. package/dist/locale/en-US.json +61 -0
  12. package/dist/locale/index.d.ts +141 -0
  13. package/dist/locale/index.js +79 -0
  14. package/dist/locale/zh-CN.json +61 -0
  15. package/dist/node_modules/ses/LICENSE +201 -0
  16. package/dist/node_modules/ses/LICENSE-aura +16 -0
  17. package/dist/node_modules/ses/LICENSE-caja +13 -0
  18. package/dist/node_modules/ses/LICENSE-corejs +19 -0
  19. package/dist/node_modules/ses/LICENSE-v8 +9 -0
  20. package/dist/node_modules/ses/assert-shim.js +1 -0
  21. package/dist/node_modules/ses/compartment-shim.js +1 -0
  22. package/dist/node_modules/ses/console-shim.js +1 -0
  23. package/dist/node_modules/ses/dist/lockdown.cjs +13912 -0
  24. package/dist/node_modules/ses/dist/lockdown.umd.js +13912 -0
  25. package/dist/node_modules/ses/dist/lockdown.umd.min.js +1 -0
  26. package/dist/node_modules/ses/dist/ses-hermes.cjs +13912 -0
  27. package/dist/node_modules/ses/dist/ses.cjs +1 -0
  28. package/dist/node_modules/ses/dist/ses.umd.js +13912 -0
  29. package/dist/node_modules/ses/dist/ses.umd.min.js +1 -0
  30. package/dist/node_modules/ses/dist/types.d.cts +606 -0
  31. package/dist/node_modules/ses/index.js +18 -0
  32. package/dist/node_modules/ses/lockdown-shim.js +1 -0
  33. package/dist/node_modules/ses/lockdown.js +1 -0
  34. package/dist/node_modules/ses/package.json +1 -0
  35. package/dist/node_modules/ses/src/assert-shim.js +4 -0
  36. package/dist/node_modules/ses/src/assert-sloppy-mode.js +11 -0
  37. package/dist/node_modules/ses/src/cauterize-property.js +69 -0
  38. package/dist/node_modules/ses/src/commons.js +425 -0
  39. package/dist/node_modules/ses/src/compartment-evaluate.js +93 -0
  40. package/dist/node_modules/ses/src/compartment-shim.js +22 -0
  41. package/dist/node_modules/ses/src/compartment.js +477 -0
  42. package/dist/node_modules/ses/src/console-shim.js +50 -0
  43. package/dist/node_modules/ses/src/enable-property-overrides.js +211 -0
  44. package/dist/node_modules/ses/src/enablements.js +244 -0
  45. package/dist/node_modules/ses/src/error/assert.js +584 -0
  46. package/dist/node_modules/ses/src/error/console.js +541 -0
  47. package/dist/node_modules/ses/src/error/fatal-assert.js +54 -0
  48. package/dist/node_modules/ses/src/error/internal-types.js +98 -0
  49. package/dist/node_modules/ses/src/error/note-log-args.js +77 -0
  50. package/dist/node_modules/ses/src/error/stringify-utils.js +195 -0
  51. package/dist/node_modules/ses/src/error/tame-console.js +197 -0
  52. package/dist/node_modules/ses/src/error/tame-error-constructor.js +284 -0
  53. package/dist/node_modules/ses/src/error/tame-v8-error-constructor.js +386 -0
  54. package/dist/node_modules/ses/src/error/types.js +59 -0
  55. package/dist/node_modules/ses/src/error/unhandled-rejection.js +122 -0
  56. package/dist/node_modules/ses/src/eval-scope.js +89 -0
  57. package/dist/node_modules/ses/src/get-anonymous-intrinsics.js +181 -0
  58. package/dist/node_modules/ses/src/get-source-url.js +50 -0
  59. package/dist/node_modules/ses/src/global-object.js +175 -0
  60. package/dist/node_modules/ses/src/intrinsics.js +192 -0
  61. package/dist/node_modules/ses/src/lockdown-shim.js +37 -0
  62. package/dist/node_modules/ses/src/lockdown.js +558 -0
  63. package/dist/node_modules/ses/src/make-eval-function.js +28 -0
  64. package/dist/node_modules/ses/src/make-evaluate.js +110 -0
  65. package/dist/node_modules/ses/src/make-function-constructor.js +79 -0
  66. package/dist/node_modules/ses/src/make-hardener.js +275 -0
  67. package/dist/node_modules/ses/src/make-safe-evaluator.js +112 -0
  68. package/dist/node_modules/ses/src/module-instance.js +497 -0
  69. package/dist/node_modules/ses/src/module-link.js +159 -0
  70. package/dist/node_modules/ses/src/module-load.js +719 -0
  71. package/dist/node_modules/ses/src/module-proxy.js +200 -0
  72. package/dist/node_modules/ses/src/permits-intrinsics.js +291 -0
  73. package/dist/node_modules/ses/src/permits.js +1761 -0
  74. package/dist/node_modules/ses/src/reporting-types.d.ts +13 -0
  75. package/dist/node_modules/ses/src/reporting.js +105 -0
  76. package/dist/node_modules/ses/src/scope-constants.js +180 -0
  77. package/dist/node_modules/ses/src/shim-arraybuffer-transfer.js +85 -0
  78. package/dist/node_modules/ses/src/sloppy-globals-scope-terminator.js +61 -0
  79. package/dist/node_modules/ses/src/strict-scope-terminator.js +99 -0
  80. package/dist/node_modules/ses/src/tame-date-constructor.js +127 -0
  81. package/dist/node_modules/ses/src/tame-domains.js +41 -0
  82. package/dist/node_modules/ses/src/tame-faux-data-properties.js +210 -0
  83. package/dist/node_modules/ses/src/tame-function-constructors.js +140 -0
  84. package/dist/node_modules/ses/src/tame-function-tostring.js +50 -0
  85. package/dist/node_modules/ses/src/tame-harden.js +29 -0
  86. package/dist/node_modules/ses/src/tame-locale-methods.js +78 -0
  87. package/dist/node_modules/ses/src/tame-math-object.js +41 -0
  88. package/dist/node_modules/ses/src/tame-module-source.js +51 -0
  89. package/dist/node_modules/ses/src/tame-regenerator-runtime.js +29 -0
  90. package/dist/node_modules/ses/src/tame-regexp-constructor.js +65 -0
  91. package/dist/node_modules/ses/src/tame-symbol-constructor.js +64 -0
  92. package/dist/node_modules/ses/src/transforms.js +267 -0
  93. package/dist/node_modules/ses/tools.js +25 -0
  94. package/dist/node_modules/ses/types.d.ts +606 -0
  95. package/dist/server/actions/ui-schema-action.d.ts +27 -0
  96. package/dist/server/actions/ui-schema-action.js +118 -0
  97. package/dist/server/collections/flowModelTreePath.d.ts +11 -0
  98. package/dist/server/collections/flowModelTreePath.js +74 -0
  99. package/dist/server/collections/flowModels.d.ts +11 -0
  100. package/dist/server/collections/flowModels.js +57 -0
  101. package/dist/server/collections/flowsql.d.ts +10 -0
  102. package/dist/server/collections/flowsql.js +51 -0
  103. package/dist/server/dao/ui_schema_node_dao.d.ts +26 -0
  104. package/dist/server/dao/ui_schema_node_dao.js +24 -0
  105. package/dist/server/helper.d.ts +8 -0
  106. package/dist/server/helper.js +9 -0
  107. package/dist/server/index.d.ts +9 -0
  108. package/dist/server/index.js +42 -0
  109. package/dist/server/model.d.ts +12 -0
  110. package/dist/server/model.js +38 -0
  111. package/dist/server/plugin.d.ts +26 -0
  112. package/dist/server/plugin.js +270 -0
  113. package/dist/server/repository.d.ts +116 -0
  114. package/dist/server/repository.js +1209 -0
  115. package/dist/server/server.d.ts +16 -0
  116. package/dist/server/server.js +198 -0
  117. package/dist/server/template/contexts.d.ts +73 -0
  118. package/dist/server/template/contexts.js +233 -0
  119. package/dist/server/template/resolver.d.ts +30 -0
  120. package/dist/server/template/resolver.js +225 -0
  121. package/dist/server/variables/registry.d.ts +42 -0
  122. package/dist/server/variables/registry.js +299 -0
  123. package/package.json +28 -0
  124. package/server.d.ts +2 -0
  125. 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
+ };