@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,719 @@
1
+ import { getEnvironmentOption as getenv } from '@endo/env-options';
2
+ import {
3
+ Map,
4
+ Set,
5
+ TypeError,
6
+ arrayJoin,
7
+ arrayMap,
8
+ arrayPush,
9
+ arraySome,
10
+ create,
11
+ freeze,
12
+ generatorNext,
13
+ generatorThrow,
14
+ getOwnPropertyNames,
15
+ isArray,
16
+ isPrimitive,
17
+ mapGet,
18
+ mapHas,
19
+ mapSet,
20
+ promiseThen,
21
+ setAdd,
22
+ values,
23
+ weakmapGet,
24
+ weakmapHas,
25
+ } from './commons.js';
26
+ import { makeError, annotateError, q, b, X } from './error/assert.js';
27
+
28
+ const noop = () => {};
29
+
30
+ const asyncTrampoline = async (generatorFunc, args, errorWrapper) => {
31
+ await null;
32
+ const iterator = generatorFunc(...args);
33
+ let result = generatorNext(iterator);
34
+ while (!result.done) {
35
+ try {
36
+ // eslint-disable-next-line no-await-in-loop
37
+ const val = await result.value;
38
+ result = generatorNext(iterator, val);
39
+ } catch (error) {
40
+ result = generatorThrow(iterator, errorWrapper(error));
41
+ }
42
+ }
43
+ return result.value;
44
+ };
45
+
46
+ const syncTrampoline = (generatorFunc, args) => {
47
+ const iterator = generatorFunc(...args);
48
+ let result = generatorNext(iterator);
49
+ while (!result.done) {
50
+ try {
51
+ result = generatorNext(iterator, result.value);
52
+ } catch (error) {
53
+ result = generatorThrow(iterator, error);
54
+ }
55
+ }
56
+ return result.value;
57
+ };
58
+
59
+ // `makeAlias` constructs compartment specifier tuples for the `aliases`
60
+ // private field of compartments.
61
+ // These aliases allow a compartment to alias an internal module specifier to a
62
+ // module specifier in an external compartment, and also to create internal
63
+ // aliases.
64
+ // Both are facilitated by the moduleMap Compartment constructor option.
65
+ export const makeAlias = (compartment, specifier) =>
66
+ freeze({ compartment, specifier });
67
+
68
+ // `resolveAll` pre-computes resolutions of all imports within the compartment
69
+ // in which a module was loaded.
70
+ const resolveAll = (imports, resolveHook, fullReferrerSpecifier) => {
71
+ const resolvedImports = create(null);
72
+ for (const importSpecifier of imports) {
73
+ const fullSpecifier = resolveHook(importSpecifier, fullReferrerSpecifier);
74
+ resolvedImports[importSpecifier] = fullSpecifier;
75
+ }
76
+ return freeze(resolvedImports);
77
+ };
78
+
79
+ const loadModuleSource = (
80
+ compartmentPrivateFields,
81
+ moduleAliases,
82
+ compartment,
83
+ moduleSpecifier,
84
+ moduleSource,
85
+ enqueueJob,
86
+ selectImplementation,
87
+ moduleLoads,
88
+ importMeta,
89
+ ) => {
90
+ const { resolveHook, name: compartmentName } = weakmapGet(
91
+ compartmentPrivateFields,
92
+ compartment,
93
+ );
94
+
95
+ const { imports } = moduleSource;
96
+ if (
97
+ !isArray(imports) ||
98
+ arraySome(imports, specifier => typeof specifier !== 'string')
99
+ ) {
100
+ throw makeError(
101
+ X`Invalid module source: 'imports' must be an array of strings, got ${imports} for module ${q(moduleSpecifier)} of compartment ${q(compartmentName)}`,
102
+ );
103
+ }
104
+
105
+ // resolve all imports relative to this referrer module.
106
+ const resolvedImports = resolveAll(imports, resolveHook, moduleSpecifier);
107
+ const moduleRecord = freeze({
108
+ compartment,
109
+ moduleSource,
110
+ moduleSpecifier,
111
+ resolvedImports,
112
+ importMeta,
113
+ });
114
+
115
+ // Enqueue jobs to load this module's shallow dependencies.
116
+ for (const fullSpecifier of values(resolvedImports)) {
117
+ // Behold: recursion.
118
+ // eslint-disable-next-line no-use-before-define
119
+ enqueueJob(memoizedLoadWithErrorAnnotation, [
120
+ compartmentPrivateFields,
121
+ moduleAliases,
122
+ compartment,
123
+ fullSpecifier,
124
+ enqueueJob,
125
+ selectImplementation,
126
+ moduleLoads,
127
+ ]);
128
+ }
129
+
130
+ return moduleRecord;
131
+ };
132
+
133
+ function* loadWithoutErrorAnnotation(
134
+ compartmentPrivateFields,
135
+ moduleAliases,
136
+ compartment,
137
+ moduleSpecifier,
138
+ enqueueJob,
139
+ selectImplementation,
140
+ moduleLoads,
141
+ ) {
142
+ const {
143
+ importHook,
144
+ importNowHook,
145
+ moduleMap,
146
+ moduleMapHook,
147
+ moduleRecords,
148
+ parentCompartment,
149
+ } = weakmapGet(compartmentPrivateFields, compartment);
150
+
151
+ if (mapHas(moduleRecords, moduleSpecifier)) {
152
+ return mapGet(moduleRecords, moduleSpecifier);
153
+ }
154
+
155
+ // Follow moduleMap, or moduleMapHook if present.
156
+ let moduleDescriptor = moduleMap[moduleSpecifier];
157
+ if (moduleDescriptor === undefined && moduleMapHook !== undefined) {
158
+ moduleDescriptor = moduleMapHook(moduleSpecifier);
159
+ }
160
+ if (moduleDescriptor === undefined) {
161
+ const moduleHook = selectImplementation(importHook, importNowHook);
162
+ if (moduleHook === undefined) {
163
+ const moduleHookName = selectImplementation(
164
+ 'importHook',
165
+ 'importNowHook',
166
+ );
167
+ throw makeError(
168
+ X`${b(moduleHookName)} needed to load module ${q(
169
+ moduleSpecifier,
170
+ )} in compartment ${q(compartment.name)}`,
171
+ );
172
+ }
173
+ moduleDescriptor = moduleHook(moduleSpecifier);
174
+ // Uninitialized module namespaces throw if we attempt to coerce them into
175
+ // promises.
176
+ if (!weakmapHas(moduleAliases, moduleDescriptor)) {
177
+ moduleDescriptor = yield moduleDescriptor;
178
+ }
179
+ }
180
+
181
+ if (typeof moduleDescriptor === 'string') {
182
+ // eslint-disable-next-line @endo/no-polymorphic-call
183
+ throw makeError(
184
+ X`Cannot map module ${q(moduleSpecifier)} to ${q(
185
+ moduleDescriptor,
186
+ )} in parent compartment, use {source} module descriptor`,
187
+ TypeError,
188
+ );
189
+ } else if (!isPrimitive(moduleDescriptor)) {
190
+ // In this shim (and not in XS, and not in the standard we imagine), we
191
+ // allow a module namespace object to stand in for a module descriptor that
192
+ // describes its original {compartment, specifier} so that it can be used
193
+ // to create a link.
194
+ let aliasDescriptor = weakmapGet(moduleAliases, moduleDescriptor);
195
+ if (aliasDescriptor !== undefined) {
196
+ moduleDescriptor = aliasDescriptor;
197
+ }
198
+
199
+ if (moduleDescriptor.namespace !== undefined) {
200
+ // { namespace: string, compartment?: Compartment }
201
+ // Namespace module descriptors link to a module instance.
202
+
203
+ if (typeof moduleDescriptor.namespace === 'string') {
204
+ // The default compartment is the *parent*, not this child compartment.
205
+ // This is a difference from the legacy {specifier, compartment} module
206
+ // descriptor.
207
+ const {
208
+ compartment: aliasCompartment = parentCompartment,
209
+ namespace: aliasSpecifier,
210
+ } = moduleDescriptor;
211
+ if (
212
+ isPrimitive(aliasCompartment) ||
213
+ !weakmapHas(compartmentPrivateFields, aliasCompartment)
214
+ ) {
215
+ throw makeError(
216
+ X`Invalid compartment in module descriptor for specifier ${q(moduleSpecifier)} in compartment ${q(compartment.name)}`,
217
+ );
218
+ }
219
+ // Behold: recursion.
220
+ // eslint-disable-next-line no-use-before-define
221
+ const aliasRecord = yield memoizedLoadWithErrorAnnotation(
222
+ compartmentPrivateFields,
223
+ moduleAliases,
224
+ aliasCompartment,
225
+ aliasSpecifier,
226
+ enqueueJob,
227
+ selectImplementation,
228
+ moduleLoads,
229
+ );
230
+ mapSet(moduleRecords, moduleSpecifier, aliasRecord);
231
+ return aliasRecord;
232
+ }
233
+
234
+ // All remaining objects must either be a module namespace, or be
235
+ // promoted into a module namespace with a virtual module source.
236
+ if (!isPrimitive(moduleDescriptor.namespace)) {
237
+ const { namespace } = moduleDescriptor;
238
+ // Brand-check SES shim module exports namespaces:
239
+ aliasDescriptor = weakmapGet(moduleAliases, namespace);
240
+ if (aliasDescriptor !== undefined) {
241
+ moduleDescriptor = aliasDescriptor;
242
+ // Fall through to processing the resulting {compartment, specifier}
243
+ // alias.
244
+ } else {
245
+ // Promote an arbitrary object to a module namespace with a virtual
246
+ // module source.
247
+ // { namespace: Object }
248
+ const exports = getOwnPropertyNames(namespace);
249
+ /** @type {import('../types.js').VirtualModuleSource} */
250
+ const moduleSource = {
251
+ imports: [],
252
+ exports,
253
+ execute(env) {
254
+ for (const name of exports) {
255
+ env[name] = namespace[name];
256
+ }
257
+ },
258
+ };
259
+ const importMeta = undefined;
260
+ const moduleRecord = loadModuleSource(
261
+ compartmentPrivateFields,
262
+ moduleAliases,
263
+ compartment,
264
+ moduleSpecifier,
265
+ moduleSource,
266
+ enqueueJob,
267
+ selectImplementation,
268
+ moduleLoads,
269
+ importMeta,
270
+ );
271
+ mapSet(moduleRecords, moduleSpecifier, moduleRecord);
272
+ return moduleRecord;
273
+ }
274
+ } else {
275
+ throw makeError(
276
+ X`Invalid compartment in module descriptor for specifier ${q(moduleSpecifier)} in compartment ${q(compartment.name)}`,
277
+ );
278
+ }
279
+ }
280
+
281
+ if (moduleDescriptor.source !== undefined) {
282
+ // Module source descriptors create an instance from a module source.
283
+ // The descriptor may contain the module source, or refer to a source
284
+ // loaded in a particular compartment.
285
+
286
+ if (typeof moduleDescriptor.source === 'string') {
287
+ // { source: string, importMeta?, specifier?: string, compartment? }
288
+ // A string source is the specifier for a different module source.
289
+ // That source may come from this compartment's parent (default), or
290
+ // from a specified compartment, and the specified compartment may be
291
+ // this compartment to make a duplicate.
292
+
293
+ const {
294
+ source: loaderSpecifier,
295
+ specifier: instanceSpecifier = moduleSpecifier,
296
+ compartment: loaderCompartment = parentCompartment,
297
+ importMeta = undefined,
298
+ } = moduleDescriptor;
299
+
300
+ // Induce the compartment, possibly a different compartment
301
+ // to load a module source.
302
+
303
+ // Behold: recursion.
304
+ // eslint-disable-next-line no-use-before-define
305
+ const loaderRecord = yield memoizedLoadWithErrorAnnotation(
306
+ compartmentPrivateFields,
307
+ moduleAliases,
308
+ loaderCompartment,
309
+ loaderSpecifier,
310
+ enqueueJob,
311
+ selectImplementation,
312
+ moduleLoads,
313
+ );
314
+
315
+ // Extract the source of the module from the loader compartment's
316
+ // record.
317
+ const { moduleSource } = loaderRecord;
318
+
319
+ // Instantiate that source in our own compartment, possibly with a
320
+ // different specifier for resolving its own imports.
321
+ const moduleRecord = loadModuleSource(
322
+ compartmentPrivateFields,
323
+ moduleAliases,
324
+ compartment,
325
+ instanceSpecifier,
326
+ moduleSource,
327
+ enqueueJob,
328
+ selectImplementation,
329
+ moduleLoads,
330
+ importMeta,
331
+ );
332
+ mapSet(moduleRecords, moduleSpecifier, moduleRecord);
333
+ return moduleRecord;
334
+ } else {
335
+ // { source: ModuleSource, importMeta?, specifier?: string }
336
+ // We assume all non-string module sources are any of the supported
337
+ // kinds of module source: PrecompiledModuleSource,
338
+ // VirtualModuleSource, or a native ModuleSource.
339
+
340
+ const {
341
+ source: moduleSource,
342
+ specifier: aliasSpecifier = moduleSpecifier,
343
+ importMeta,
344
+ } = moduleDescriptor;
345
+
346
+ const aliasRecord = loadModuleSource(
347
+ compartmentPrivateFields,
348
+ moduleAliases,
349
+ compartment,
350
+ aliasSpecifier,
351
+ moduleSource,
352
+ enqueueJob,
353
+ selectImplementation,
354
+ moduleLoads,
355
+ importMeta,
356
+ );
357
+ mapSet(moduleRecords, moduleSpecifier, aliasRecord);
358
+ return aliasRecord;
359
+ }
360
+ }
361
+
362
+ if (moduleDescriptor.archive !== undefined) {
363
+ // { archive: Archive, path: string }
364
+ // We do not support this XS-native module descriptor.
365
+ throw makeError(
366
+ X`Unsupported archive module descriptor for specifier ${q(moduleSpecifier)} in compartment ${q(compartment.name)}`,
367
+ );
368
+ }
369
+
370
+ // { record, specifier?, compartment?, importMeta? }
371
+ // A (legacy) module descriptor for when we find the module source (record)
372
+ // but at a different specifier than requested.
373
+ // Providing this {specifier, record} descriptor serves as an ergonomic
374
+ // short-hand for stashing the record, returning a {compartment, specifier}
375
+ // reference, bouncing the module hook, then producing the source (record)
376
+ // when module hook receives the response specifier.
377
+ if (moduleDescriptor.record !== undefined) {
378
+ const {
379
+ compartment: aliasCompartment = compartment,
380
+ specifier: aliasSpecifier = moduleSpecifier,
381
+ record: moduleSource,
382
+ importMeta,
383
+ } = moduleDescriptor;
384
+
385
+ const aliasRecord = loadModuleSource(
386
+ compartmentPrivateFields,
387
+ moduleAliases,
388
+ aliasCompartment,
389
+ aliasSpecifier,
390
+ moduleSource,
391
+ enqueueJob,
392
+ selectImplementation,
393
+ moduleLoads,
394
+ importMeta,
395
+ );
396
+ mapSet(moduleRecords, moduleSpecifier, aliasRecord);
397
+ mapSet(moduleRecords, aliasSpecifier, aliasRecord);
398
+ return aliasRecord;
399
+ }
400
+
401
+ // { specifier: string, compartment: Compartment }
402
+ // A (legacy) module descriptor that describes a link to a module instance
403
+ // in a specified compartment.
404
+ if (
405
+ moduleDescriptor.compartment !== undefined &&
406
+ moduleDescriptor.specifier !== undefined
407
+ ) {
408
+ if (
409
+ isPrimitive(moduleDescriptor.compartment) ||
410
+ !weakmapHas(compartmentPrivateFields, moduleDescriptor.compartment) ||
411
+ typeof moduleDescriptor.specifier !== 'string'
412
+ ) {
413
+ throw makeError(
414
+ X`Invalid compartment in module descriptor for specifier ${q(moduleSpecifier)} in compartment ${q(compartment.name)}`,
415
+ );
416
+ }
417
+ // Behold: recursion.
418
+ // eslint-disable-next-line no-use-before-define
419
+ const aliasRecord = yield memoizedLoadWithErrorAnnotation(
420
+ compartmentPrivateFields,
421
+ moduleAliases,
422
+ moduleDescriptor.compartment,
423
+ moduleDescriptor.specifier,
424
+ enqueueJob,
425
+ selectImplementation,
426
+ moduleLoads,
427
+ );
428
+ mapSet(moduleRecords, moduleSpecifier, aliasRecord);
429
+ return aliasRecord;
430
+ }
431
+
432
+ // A (legacy) behavior: If we do not recognize the module descriptor as a
433
+ // module descriptor, we assume that it is a module source (record):
434
+ const moduleSource = moduleDescriptor;
435
+ const moduleRecord = loadModuleSource(
436
+ compartmentPrivateFields,
437
+ moduleAliases,
438
+ compartment,
439
+ moduleSpecifier,
440
+ moduleSource,
441
+ enqueueJob,
442
+ selectImplementation,
443
+ moduleLoads,
444
+ );
445
+ // Memoize.
446
+ mapSet(moduleRecords, moduleSpecifier, moduleRecord);
447
+ return moduleRecord;
448
+ } else {
449
+ throw makeError(
450
+ X`module descriptor must be a string or object for specifier ${q(
451
+ moduleSpecifier,
452
+ )} in compartment ${q(compartment.name)}`,
453
+ );
454
+ }
455
+ }
456
+
457
+ const memoizedLoadWithErrorAnnotation = (
458
+ compartmentPrivateFields,
459
+ moduleAliases,
460
+ compartment,
461
+ moduleSpecifier,
462
+ enqueueJob,
463
+ selectImplementation,
464
+ moduleLoads,
465
+ ) => {
466
+ const { name: compartmentName } = weakmapGet(
467
+ compartmentPrivateFields,
468
+ compartment,
469
+ );
470
+
471
+ // Prevent data-lock from recursion into branches visited in dependent loads.
472
+ let compartmentLoading = mapGet(moduleLoads, compartment);
473
+ if (compartmentLoading === undefined) {
474
+ compartmentLoading = new Map();
475
+ mapSet(moduleLoads, compartment, compartmentLoading);
476
+ }
477
+ let moduleLoading = mapGet(compartmentLoading, moduleSpecifier);
478
+ if (moduleLoading !== undefined) {
479
+ return moduleLoading;
480
+ }
481
+
482
+ moduleLoading = selectImplementation(asyncTrampoline, syncTrampoline)(
483
+ loadWithoutErrorAnnotation,
484
+ [
485
+ compartmentPrivateFields,
486
+ moduleAliases,
487
+ compartment,
488
+ moduleSpecifier,
489
+ enqueueJob,
490
+ selectImplementation,
491
+ moduleLoads,
492
+ ],
493
+ error => {
494
+ // eslint-disable-next-line @endo/no-polymorphic-call
495
+ annotateError(
496
+ error,
497
+ X`${error.message}, loading ${q(moduleSpecifier)} in compartment ${q(
498
+ compartmentName,
499
+ )}`,
500
+ );
501
+ throw error;
502
+ },
503
+ );
504
+
505
+ mapSet(compartmentLoading, moduleSpecifier, moduleLoading);
506
+
507
+ return moduleLoading;
508
+ };
509
+
510
+ /**
511
+ * If `aggregateErrors` is `false`, the `errors` property of the fulfilled object
512
+ * will always be empty.
513
+ * @param {{errors?: Error[], noAggregateErrors?: boolean}} [options]
514
+ */
515
+ const asyncJobQueue = ({ errors = [], noAggregateErrors = false } = {}) => {
516
+ /** @type {Set<Promise<undefined>>} */
517
+ const pendingJobs = new Set();
518
+
519
+ /**
520
+ * Enqueues a job that starts immediately but won't be awaited until drainQueue is called.
521
+ *
522
+ * @template {(...args: any[]) => Promise<void>} F
523
+ * @param {F} func - An async function to execute
524
+ * @param {Parameters<F>} args - Arguments to pass to the function
525
+ * @returns {void}
526
+ */
527
+ const enqueueJob = (func, args) => {
528
+ setAdd(
529
+ pendingJobs,
530
+ promiseThen(func(...args), noop, error => {
531
+ if (noAggregateErrors) {
532
+ throw error;
533
+ } else {
534
+ arrayPush(errors, error);
535
+ }
536
+ }),
537
+ );
538
+ };
539
+ /**
540
+ * Sequentially awaits pending jobs and returns an array of errors
541
+ */
542
+ const drainQueue = async () => {
543
+ await null;
544
+ for (const job of pendingJobs) {
545
+ // eslint-disable-next-line no-await-in-loop
546
+ await job;
547
+ }
548
+ };
549
+ return { enqueueJob, drainQueue, errors };
550
+ };
551
+
552
+ /**
553
+ * If `aggregateErrors` is `false`, the `errors` property of the returned object
554
+ * will always be empty.
555
+ * @param {{errors?: Error[], noAggregateErrors?: boolean}} [options]
556
+ */
557
+ const syncJobQueue = ({ errors = [], noAggregateErrors = false } = {}) => {
558
+ let current = [];
559
+ let next = [];
560
+
561
+ /**
562
+ * Enqueues a job
563
+ *
564
+ * @template {(...args: any[]) => void} F
565
+ * @param {F} func - An async function to execute
566
+ * @param {Parameters<F>} args - Arguments to pass to the function
567
+ * @returns {void}
568
+ */
569
+ const enqueueJob = (func, args) => {
570
+ arrayPush(next, [func, args]);
571
+ };
572
+ const drainQueue = () => {
573
+ // Attention: load bearing flow order. Calling another enqueued function in the
574
+ // synchronous usecase must happen after the one that enqueued it has finished.
575
+ // Jobs enqueued in one pass do not interleave with jobs resulting from them.
576
+ // It's necessary for efficient memoization and to break cycles.
577
+ for (const [func, args] of current) {
578
+ try {
579
+ func(...args);
580
+ } catch (error) {
581
+ if (noAggregateErrors) {
582
+ throw error;
583
+ } else {
584
+ arrayPush(errors, error);
585
+ }
586
+ }
587
+ }
588
+ current = next;
589
+ next = [];
590
+ if (current.length > 0) drainQueue();
591
+ };
592
+ return { enqueueJob, drainQueue, errors };
593
+ };
594
+
595
+ /**
596
+ * @param {object} options
597
+ * @param {Array<Error>} options.errors
598
+ * @param {string} options.errorPrefix
599
+ */
600
+ const throwAggregateError = ({ errors, errorPrefix }) => {
601
+ // Throw an aggregate error if there were any errors.
602
+ if (errors.length > 0) {
603
+ const verbose =
604
+ /** @type {'' | 'verbose'} */
605
+ (getenv('COMPARTMENT_LOAD_ERRORS', '', ['verbose'])) === 'verbose';
606
+ throw TypeError(
607
+ `${errorPrefix} (${errors.length} underlying failures: ${arrayJoin(
608
+ arrayMap(errors, error => error.message + (verbose ? error.stack : '')),
609
+ ', ',
610
+ )}`,
611
+ );
612
+ }
613
+ };
614
+
615
+ const preferSync = (_asyncImpl, syncImpl) => syncImpl;
616
+ const preferAsync = (asyncImpl, _syncImpl) => asyncImpl;
617
+
618
+ /**
619
+ * `load` asynchronously gathers the module records for a module and its
620
+ * transitive dependencies.
621
+ * The module records refer to each other by a reference to the dependency's
622
+ * compartment and the specifier of the module within its own compartment.
623
+ * This graph is then ready to be synchronously linked and executed.
624
+ * @param {WeakMap<Compartment, any>} compartmentPrivateFields
625
+ * @param {WeakMap<object, object>} moduleAliases
626
+ * @param {Compartment} compartment
627
+ * @param {string} moduleSpecifier - The module specifier to load.
628
+ * @param {{ noAggregateErrors?: boolean}} options
629
+ */
630
+ export const load = async (
631
+ compartmentPrivateFields,
632
+ moduleAliases,
633
+ compartment,
634
+ moduleSpecifier,
635
+ { noAggregateErrors = false } = {},
636
+ ) => {
637
+ const { name: compartmentName } = weakmapGet(
638
+ compartmentPrivateFields,
639
+ compartment,
640
+ );
641
+
642
+ /** @type {Map<object, Map<string, Promise<Record<any, any>>>>} */
643
+ const moduleLoads = new Map();
644
+
645
+ const { enqueueJob, drainQueue, errors } = asyncJobQueue({
646
+ noAggregateErrors,
647
+ });
648
+
649
+ enqueueJob(memoizedLoadWithErrorAnnotation, [
650
+ compartmentPrivateFields,
651
+ moduleAliases,
652
+ compartment,
653
+ moduleSpecifier,
654
+ enqueueJob,
655
+ preferAsync,
656
+ moduleLoads,
657
+ ]);
658
+
659
+ await drainQueue();
660
+
661
+ throwAggregateError({
662
+ errors,
663
+ errorPrefix: `Failed to load module ${q(moduleSpecifier)} in package ${q(
664
+ compartmentName,
665
+ )}`,
666
+ });
667
+ };
668
+
669
+ /**
670
+ * `loadNow` synchronously gathers the module records for a specified module
671
+ * and its transitive dependencies.
672
+ * The module records refer to each other by a reference to the dependency's
673
+ * compartment and the specifier of the module within its own compartment.
674
+ * This graph is then ready to be synchronously linked and executed.
675
+ * @param {WeakMap<Compartment, any>} compartmentPrivateFields
676
+ * @param {WeakMap<object, object>} moduleAliases
677
+ * @param {Compartment} compartment
678
+ * @param {string} moduleSpecifier - The module specifier to load.
679
+ * @param {{ noAggregateErrors?: boolean}} options
680
+ */
681
+
682
+ export const loadNow = (
683
+ compartmentPrivateFields,
684
+ moduleAliases,
685
+ compartment,
686
+ moduleSpecifier,
687
+ { noAggregateErrors = false } = {},
688
+ ) => {
689
+ const { name: compartmentName } = weakmapGet(
690
+ compartmentPrivateFields,
691
+ compartment,
692
+ );
693
+
694
+ /** @type {Map<object, Map<string, Promise<Record<any, any>>>>} */
695
+ const moduleLoads = new Map();
696
+
697
+ const { enqueueJob, drainQueue, errors } = syncJobQueue({
698
+ noAggregateErrors,
699
+ });
700
+
701
+ enqueueJob(memoizedLoadWithErrorAnnotation, [
702
+ compartmentPrivateFields,
703
+ moduleAliases,
704
+ compartment,
705
+ moduleSpecifier,
706
+ enqueueJob,
707
+ preferSync,
708
+ moduleLoads,
709
+ ]);
710
+
711
+ drainQueue();
712
+
713
+ throwAggregateError({
714
+ errors,
715
+ errorPrefix: `Failed to load module ${q(moduleSpecifier)} in package ${q(
716
+ compartmentName,
717
+ )}`,
718
+ });
719
+ };