@jsenv/core 28.0.0 → 28.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (67) hide show
  1. package/dist/controllable_child_process.mjs +1 -2
  2. package/dist/controllable_worker_thread.mjs +1 -2
  3. package/dist/js/autoreload.js +27 -11
  4. package/dist/js/execute_using_dynamic_import.js +804 -1
  5. package/dist/js/script_type_module_supervisor.js +129 -0
  6. package/dist/js/supervisor.js +921 -0
  7. package/dist/js/{wrapper.mjs → ws.js} +0 -0
  8. package/dist/main.js +555 -616
  9. package/package.json +13 -13
  10. package/readme.md +2 -2
  11. package/src/build/build.js +8 -8
  12. package/src/build/inject_global_version_mappings.js +3 -3
  13. package/src/build/{resync_ressource_hints.js → resync_resource_hints.js} +10 -12
  14. package/src/build/start_build_server.js +4 -7
  15. package/src/dev/start_dev_server.js +2 -2
  16. package/src/execute/execute.js +1 -1
  17. package/src/execute/run.js +26 -38
  18. package/src/execute/runtimes/browsers/from_playwright.js +51 -77
  19. package/src/execute/runtimes/node/node_child_process.js +36 -36
  20. package/src/execute/runtimes/node/node_worker_thread.js +36 -36
  21. package/src/omega/kitchen.js +33 -14
  22. package/src/omega/omega_server.js +2 -2
  23. package/src/omega/server/file_service.js +5 -5
  24. package/src/omega/url_graph/url_graph_load.js +4 -4
  25. package/src/omega/url_graph/url_info_transformations.js +8 -1
  26. package/src/omega/url_graph.js +3 -3
  27. package/src/plugins/autoreload/client/reload.js +22 -9
  28. package/src/plugins/autoreload/jsenv_plugin_autoreload_client.js +5 -5
  29. package/src/plugins/autoreload/jsenv_plugin_autoreload_server.js +3 -3
  30. package/src/plugins/autoreload/jsenv_plugin_hmr.js +1 -1
  31. package/src/plugins/explorer/jsenv_plugin_explorer.js +1 -1
  32. package/src/plugins/import_meta_hot/html_hot_dependencies.js +6 -6
  33. package/src/plugins/importmap/jsenv_plugin_importmap.js +5 -3
  34. package/src/plugins/inject_globals/inject_globals.js +3 -3
  35. package/src/plugins/inline/jsenv_plugin_data_urls.js +1 -1
  36. package/src/plugins/inline/jsenv_plugin_html_inline_content.js +10 -5
  37. package/src/plugins/node_esm_resolution/jsenv_plugin_node_esm_resolution.js +2 -13
  38. package/src/plugins/plugin_controller.js +2 -2
  39. package/src/plugins/plugins.js +5 -5
  40. package/src/plugins/server_events/jsenv_plugin_server_events_client_injection.js +4 -4
  41. package/src/plugins/supervisor/client/script_type_module_supervisor.js +108 -0
  42. package/src/plugins/supervisor/client/supervisor.js +921 -0
  43. package/src/plugins/{html_supervisor/jsenv_plugin_html_supervisor.js → supervisor/jsenv_plugin_supervisor.js} +131 -105
  44. package/src/plugins/toolbar/client/execution/toolbar_execution.js +1 -1
  45. package/src/plugins/toolbar/jsenv_plugin_toolbar.js +5 -5
  46. package/src/plugins/transpilation/as_js_classic/jsenv_plugin_as_js_classic.js +9 -7
  47. package/src/plugins/transpilation/as_js_classic/jsenv_plugin_as_js_classic_html.js +8 -7
  48. package/src/plugins/transpilation/babel/jsenv_plugin_babel.js +13 -7
  49. package/src/plugins/transpilation/babel/new_stylesheet/babel_plugin_new_stylesheet_as_jsenv_import.js +6 -4
  50. package/src/plugins/transpilation/jsenv_plugin_transpilation.js +4 -2
  51. package/src/plugins/url_analysis/html/html_urls.js +13 -12
  52. package/src/plugins/url_analysis/jsenv_plugin_url_analysis.js +1 -1
  53. package/src/test/coverage/babel_plugin_instrument.js +1 -35
  54. package/src/test/coverage/empty_coverage_factory.js +1 -1
  55. package/src/test/execute_plan.js +7 -3
  56. package/src/test/execute_test_plan.js +2 -1
  57. package/src/test/logs_file_execution.js +49 -8
  58. package/dist/js/html_supervisor_installer.js +0 -1091
  59. package/dist/js/html_supervisor_setup.js +0 -89
  60. package/dist/js/uneval.js +0 -804
  61. package/src/plugins/html_supervisor/client/error_formatter.js +0 -426
  62. package/src/plugins/html_supervisor/client/error_in_notification.js +0 -21
  63. package/src/plugins/html_supervisor/client/error_overlay.js +0 -191
  64. package/src/plugins/html_supervisor/client/html_supervisor_installer.js +0 -315
  65. package/src/plugins/html_supervisor/client/html_supervisor_setup.js +0 -89
  66. package/src/plugins/html_supervisor/client/perf_browser.js +0 -17
  67. package/src/plugins/html_supervisor/client/uneval_exception.js +0 -8
package/dist/js/uneval.js DELETED
@@ -1,804 +0,0 @@
1
- // https://developer.mozilla.org/en-US/docs/Glossary/Primitive
2
- const isComposite = value => {
3
- if (value === null) {
4
- return false;
5
- }
6
-
7
- const type = typeof value;
8
-
9
- if (type === "object") {
10
- return true;
11
- }
12
-
13
- if (type === "function") {
14
- return true;
15
- }
16
-
17
- return false;
18
- };
19
-
20
- const compositeWellKnownMap = new WeakMap();
21
- const primitiveWellKnownMap = new Map();
22
- const getCompositeGlobalPath = value => compositeWellKnownMap.get(value);
23
- const getPrimitiveGlobalPath = value => primitiveWellKnownMap.get(value);
24
-
25
- const visitGlobalObject = value => {
26
- const visitValue = (value, path) => {
27
- if (isComposite(value)) {
28
- // prevent infinite recursion
29
- if (compositeWellKnownMap.has(value)) {
30
- return;
31
- }
32
-
33
- compositeWellKnownMap.set(value, path);
34
-
35
- const visitProperty = property => {
36
- let descriptor;
37
-
38
- try {
39
- descriptor = Object.getOwnPropertyDescriptor(value, property);
40
- } catch (e) {
41
- if (e.name === "SecurityError") {
42
- return;
43
- }
44
-
45
- throw e;
46
- }
47
-
48
- if (!descriptor) {
49
- // it's apparently possible to have getOwnPropertyNames returning
50
- // a property that later returns a null descriptor
51
- // for instance window.showModalDialog in webkit 13.0
52
- return;
53
- } // do not trigger getter/setter
54
-
55
-
56
- if ("value" in descriptor) {
57
- const propertyValue = descriptor.value;
58
- visitValue(propertyValue, [...path, property]);
59
- }
60
- };
61
-
62
- Object.getOwnPropertyNames(value).forEach(name => visitProperty(name));
63
- Object.getOwnPropertySymbols(value).forEach(symbol => visitProperty(symbol));
64
- }
65
-
66
- primitiveWellKnownMap.set(value, path);
67
- return;
68
- };
69
-
70
- visitValue(value, []);
71
- };
72
-
73
- if (typeof window === "object") visitGlobalObject(window);
74
- if (typeof global === "object") visitGlobalObject(global);
75
-
76
- /**
77
- * transforms a javascript value into an object describing it.
78
- *
79
- */
80
- const decompose = (mainValue, {
81
- functionAllowed,
82
- prototypeStrict,
83
- ignoreSymbols
84
- }) => {
85
- const valueMap = {};
86
- const recipeArray = [];
87
-
88
- const valueToIdentifier = (value, path = []) => {
89
- if (!isComposite(value)) {
90
- const existingIdentifier = identifierForPrimitive(value);
91
-
92
- if (existingIdentifier !== undefined) {
93
- return existingIdentifier;
94
- }
95
-
96
- const identifier = identifierForNewValue(value);
97
- recipeArray[identifier] = primitiveToRecipe(value);
98
- return identifier;
99
- }
100
-
101
- if (typeof Promise === "function" && value instanceof Promise) {
102
- throw new Error(createPromiseAreNotSupportedMessage({
103
- path
104
- }));
105
- }
106
-
107
- if (typeof WeakSet === "function" && value instanceof WeakSet) {
108
- throw new Error(createWeakSetAreNotSupportedMessage({
109
- path
110
- }));
111
- }
112
-
113
- if (typeof WeakMap === "function" && value instanceof WeakMap) {
114
- throw new Error(createWeakMapAreNotSupportedMessage({
115
- path
116
- }));
117
- }
118
-
119
- if (typeof value === "function" && !functionAllowed) {
120
- throw new Error(createForbiddenFunctionMessage({
121
- path
122
- }));
123
- }
124
-
125
- const existingIdentifier = identifierForComposite(value);
126
-
127
- if (existingIdentifier !== undefined) {
128
- return existingIdentifier;
129
- }
130
-
131
- const identifier = identifierForNewValue(value);
132
- const compositeGlobalPath = getCompositeGlobalPath(value);
133
-
134
- if (compositeGlobalPath) {
135
- recipeArray[identifier] = createGlobalReferenceRecipe(compositeGlobalPath);
136
- return identifier;
137
- }
138
-
139
- const propertyDescriptionArray = [];
140
- Object.getOwnPropertyNames(value).forEach(propertyName => {
141
- const propertyDescriptor = Object.getOwnPropertyDescriptor(value, propertyName);
142
- const propertyNameIdentifier = valueToIdentifier(propertyName, [...path, propertyName]);
143
- const propertyDescription = computePropertyDescription(propertyDescriptor, propertyName, path);
144
- propertyDescriptionArray.push({
145
- propertyNameIdentifier,
146
- propertyDescription
147
- });
148
- });
149
- const symbolDescriptionArray = [];
150
-
151
- if (!ignoreSymbols) {
152
- Object.getOwnPropertySymbols(value).forEach(symbol => {
153
- const propertyDescriptor = Object.getOwnPropertyDescriptor(value, symbol);
154
- const symbolIdentifier = valueToIdentifier(symbol, [...path, `[${symbol.toString()}]`]);
155
- const propertyDescription = computePropertyDescription(propertyDescriptor, symbol, path);
156
- symbolDescriptionArray.push({
157
- symbolIdentifier,
158
- propertyDescription
159
- });
160
- });
161
- }
162
-
163
- const methodDescriptionArray = computeMethodDescriptionArray(value, path);
164
- const extensible = Object.isExtensible(value);
165
- recipeArray[identifier] = createCompositeRecipe({
166
- propertyDescriptionArray,
167
- symbolDescriptionArray,
168
- methodDescriptionArray,
169
- extensible
170
- });
171
- return identifier;
172
- };
173
-
174
- const computePropertyDescription = (propertyDescriptor, propertyNameOrSymbol, path) => {
175
- if (propertyDescriptor.set && !functionAllowed) {
176
- throw new Error(createForbiddenPropertySetterMessage({
177
- path,
178
- propertyNameOrSymbol
179
- }));
180
- }
181
-
182
- if (propertyDescriptor.get && !functionAllowed) {
183
- throw new Error(createForbiddenPropertyGetterMessage({
184
- path,
185
- propertyNameOrSymbol
186
- }));
187
- }
188
-
189
- return {
190
- configurable: propertyDescriptor.configurable,
191
- writable: propertyDescriptor.writable,
192
- enumerable: propertyDescriptor.enumerable,
193
- getIdentifier: "get" in propertyDescriptor ? valueToIdentifier(propertyDescriptor.get, [...path, String(propertyNameOrSymbol), "[[descriptor:get]]"]) : undefined,
194
- setIdentifier: "set" in propertyDescriptor ? valueToIdentifier(propertyDescriptor.set, [...path, String(propertyNameOrSymbol), "[[descriptor:set]]"]) : undefined,
195
- valueIdentifier: "value" in propertyDescriptor ? valueToIdentifier(propertyDescriptor.value, [...path, String(propertyNameOrSymbol), "[[descriptor:value]]"]) : undefined
196
- };
197
- };
198
-
199
- const computeMethodDescriptionArray = (value, path) => {
200
- const methodDescriptionArray = [];
201
-
202
- if (typeof Set === "function" && value instanceof Set) {
203
- const callArray = [];
204
- value.forEach((entryValue, index) => {
205
- const entryValueIdentifier = valueToIdentifier(entryValue, [...path, `[[SetEntryValue]]`, index]);
206
- callArray.push([entryValueIdentifier]);
207
- });
208
- methodDescriptionArray.push({
209
- methodNameIdentifier: valueToIdentifier("add"),
210
- callArray
211
- });
212
- }
213
-
214
- if (typeof Map === "function" && value instanceof Map) {
215
- const callArray = [];
216
- value.forEach((entryValue, entryKey) => {
217
- const entryKeyIdentifier = valueToIdentifier(entryKey, [...path, "[[MapEntryKey]]", entryKey]);
218
- const entryValueIdentifier = valueToIdentifier(entryValue, [...path, "[[MapEntryValue]]", entryValue]);
219
- callArray.push([entryKeyIdentifier, entryValueIdentifier]);
220
- });
221
- methodDescriptionArray.push({
222
- methodNameIdentifier: valueToIdentifier("set"),
223
- callArray
224
- });
225
- }
226
-
227
- return methodDescriptionArray;
228
- };
229
-
230
- const identifierForPrimitive = value => {
231
- return Object.keys(valueMap).find(existingIdentifier => {
232
- const existingValue = valueMap[existingIdentifier];
233
- if (Object.is(value, existingValue)) return true;
234
- return value === existingValue;
235
- });
236
- };
237
-
238
- const identifierForComposite = value => {
239
- return Object.keys(valueMap).find(existingIdentifier => {
240
- const existingValue = valueMap[existingIdentifier];
241
- return value === existingValue;
242
- });
243
- };
244
-
245
- const identifierForNewValue = value => {
246
- const identifier = nextIdentifier();
247
- valueMap[identifier] = value;
248
- return identifier;
249
- };
250
-
251
- let currentIdentifier = -1;
252
-
253
- const nextIdentifier = () => {
254
- const identifier = String(parseInt(currentIdentifier) + 1);
255
- currentIdentifier = identifier;
256
- return identifier;
257
- };
258
-
259
- const mainIdentifier = valueToIdentifier(mainValue); // prototype, important to keep after the whole structure was visited
260
- // so that we discover if any prototype is part of the value
261
-
262
- const prototypeValueToIdentifier = prototypeValue => {
263
- // prototype is null
264
- if (prototypeValue === null) {
265
- return valueToIdentifier(prototypeValue);
266
- } // prototype found somewhere already
267
-
268
-
269
- const prototypeExistingIdentifier = identifierForComposite(prototypeValue);
270
-
271
- if (prototypeExistingIdentifier !== undefined) {
272
- return prototypeExistingIdentifier;
273
- } // mark prototype as visited
274
-
275
-
276
- const prototypeIdentifier = identifierForNewValue(prototypeValue); // prototype is a global reference ?
277
-
278
- const prototypeGlobalPath = getCompositeGlobalPath(prototypeValue);
279
-
280
- if (prototypeGlobalPath) {
281
- recipeArray[prototypeIdentifier] = createGlobalReferenceRecipe(prototypeGlobalPath);
282
- return prototypeIdentifier;
283
- } // otherwise prototype is unknown
284
-
285
-
286
- if (prototypeStrict) {
287
- throw new Error(createUnknownPrototypeMessage({
288
- prototypeValue
289
- }));
290
- }
291
-
292
- return prototypeValueToIdentifier(Object.getPrototypeOf(prototypeValue));
293
- };
294
-
295
- const identifierForValueOf = (value, path = []) => {
296
- if (value instanceof Array) {
297
- return valueToIdentifier(value.length, [...path, "length"]);
298
- }
299
-
300
- if ("valueOf" in value === false) {
301
- return undefined;
302
- }
303
-
304
- if (typeof value.valueOf !== "function") {
305
- return undefined;
306
- }
307
-
308
- const valueOfReturnValue = value.valueOf();
309
-
310
- if (!isComposite(valueOfReturnValue)) {
311
- return valueToIdentifier(valueOfReturnValue, [...path, "valueOf()"]);
312
- }
313
-
314
- if (valueOfReturnValue === value) {
315
- return undefined;
316
- }
317
-
318
- throw new Error(createUnexpectedValueOfReturnValueMessage());
319
- };
320
-
321
- recipeArray.slice().forEach((recipe, index) => {
322
- if (recipe.type === "composite") {
323
- const value = valueMap[index];
324
-
325
- if (typeof value === "function") {
326
- const valueOfIdentifier = nextIdentifier();
327
- recipeArray[valueOfIdentifier] = {
328
- type: "primitive",
329
- value
330
- };
331
- recipe.valueOfIdentifier = valueOfIdentifier;
332
- return;
333
- }
334
-
335
- if (value instanceof RegExp) {
336
- const valueOfIdentifier = nextIdentifier();
337
- recipeArray[valueOfIdentifier] = {
338
- type: "primitive",
339
- value
340
- };
341
- recipe.valueOfIdentifier = valueOfIdentifier;
342
- return;
343
- } // valueOf, mandatory to uneval new Date(10) for instance.
344
-
345
-
346
- recipe.valueOfIdentifier = identifierForValueOf(value);
347
- const prototypeValue = Object.getPrototypeOf(value);
348
- recipe.prototypeIdentifier = prototypeValueToIdentifier(prototypeValue);
349
- }
350
- });
351
- return {
352
- recipeArray,
353
- mainIdentifier,
354
- valueMap
355
- };
356
- };
357
-
358
- const primitiveToRecipe = value => {
359
- if (typeof value === "symbol") {
360
- return symbolToRecipe(value);
361
- }
362
-
363
- return createPimitiveRecipe(value);
364
- };
365
-
366
- const symbolToRecipe = symbol => {
367
- const globalSymbolKey = Symbol.keyFor(symbol);
368
-
369
- if (globalSymbolKey !== undefined) {
370
- return createGlobalSymbolRecipe(globalSymbolKey);
371
- }
372
-
373
- const symbolGlobalPath = getPrimitiveGlobalPath(symbol);
374
-
375
- if (!symbolGlobalPath) {
376
- throw new Error(createUnknownSymbolMessage({
377
- symbol
378
- }));
379
- }
380
-
381
- return createGlobalReferenceRecipe(symbolGlobalPath);
382
- };
383
-
384
- const createPimitiveRecipe = value => {
385
- return {
386
- type: "primitive",
387
- value
388
- };
389
- };
390
-
391
- const createGlobalReferenceRecipe = path => {
392
- const recipe = {
393
- type: "global-reference",
394
- path
395
- };
396
- return recipe;
397
- };
398
-
399
- const createGlobalSymbolRecipe = key => {
400
- return {
401
- type: "global-symbol",
402
- key
403
- };
404
- };
405
-
406
- const createCompositeRecipe = ({
407
- prototypeIdentifier,
408
- valueOfIdentifier,
409
- propertyDescriptionArray,
410
- symbolDescriptionArray,
411
- methodDescriptionArray,
412
- extensible
413
- }) => {
414
- return {
415
- type: "composite",
416
- prototypeIdentifier,
417
- valueOfIdentifier,
418
- propertyDescriptionArray,
419
- symbolDescriptionArray,
420
- methodDescriptionArray,
421
- extensible
422
- };
423
- };
424
-
425
- const createPromiseAreNotSupportedMessage = ({
426
- path
427
- }) => {
428
- if (path.length === 0) {
429
- return `promise are not supported.`;
430
- }
431
-
432
- return `promise are not supported.
433
- promise found at: ${path.join("")}`;
434
- };
435
-
436
- const createWeakSetAreNotSupportedMessage = ({
437
- path
438
- }) => {
439
- if (path.length === 0) {
440
- return `weakSet are not supported.`;
441
- }
442
-
443
- return `weakSet are not supported.
444
- weakSet found at: ${path.join("")}`;
445
- };
446
-
447
- const createWeakMapAreNotSupportedMessage = ({
448
- path
449
- }) => {
450
- if (path.length === 0) {
451
- return `weakMap are not supported.`;
452
- }
453
-
454
- return `weakMap are not supported.
455
- weakMap found at: ${path.join("")}`;
456
- };
457
-
458
- const createForbiddenFunctionMessage = ({
459
- path
460
- }) => {
461
- if (path.length === 0) {
462
- return `function are not allowed.`;
463
- }
464
-
465
- return `function are not allowed.
466
- function found at: ${path.join("")}`;
467
- };
468
-
469
- const createForbiddenPropertyGetterMessage = ({
470
- path,
471
- propertyNameOrSymbol
472
- }) => `property getter are not allowed.
473
- getter found on property: ${String(propertyNameOrSymbol)}
474
- at: ${path.join("")}`;
475
-
476
- const createForbiddenPropertySetterMessage = ({
477
- path,
478
- propertyNameOrSymbol
479
- }) => `property setter are not allowed.
480
- setter found on property: ${String(propertyNameOrSymbol)}
481
- at: ${path.join("")}`;
482
-
483
- const createUnexpectedValueOfReturnValueMessage = () => `valueOf() must return a primitive of the object itself.`;
484
-
485
- const createUnknownSymbolMessage = ({
486
- symbol
487
- }) => `symbol must be global, like Symbol.iterator, or created using Symbol.for().
488
- symbol: ${symbol.toString()}`;
489
-
490
- const createUnknownPrototypeMessage = ({
491
- prototypeValue
492
- }) => `prototype must be global, like Object.prototype, or somewhere in the value.
493
- prototype constructor name: ${prototypeValue.constructor.name}`;
494
-
495
- // be carefull because this function is mutating recipe objects inside the recipeArray.
496
- // this is not an issue because each recipe object is not accessible from the outside
497
- // when used internally by uneval
498
- const sortRecipe = recipeArray => {
499
- const findInRecipePrototypeChain = (recipe, callback) => {
500
- let currentRecipe = recipe; // eslint-disable-next-line no-constant-condition
501
-
502
- while (true) {
503
- if (currentRecipe.type !== "composite") {
504
- break;
505
- }
506
-
507
- const prototypeIdentifier = currentRecipe.prototypeIdentifier;
508
-
509
- if (prototypeIdentifier === undefined) {
510
- break;
511
- }
512
-
513
- currentRecipe = recipeArray[prototypeIdentifier];
514
-
515
- if (callback(currentRecipe, prototypeIdentifier)) {
516
- return prototypeIdentifier;
517
- }
518
- }
519
-
520
- return undefined;
521
- };
522
-
523
- const recipeArrayOrdered = recipeArray.slice();
524
- recipeArrayOrdered.sort((leftRecipe, rightRecipe) => {
525
- const leftType = leftRecipe.type;
526
- const rightType = rightRecipe.type;
527
-
528
- if (leftType === "composite" && rightType === "composite") {
529
- const rightRecipeIsInLeftRecipePrototypeChain = findInRecipePrototypeChain(leftRecipe, recipeCandidate => recipeCandidate === rightRecipe); // if left recipe requires right recipe, left must be after right
530
-
531
- if (rightRecipeIsInLeftRecipePrototypeChain) {
532
- return 1;
533
- }
534
-
535
- const leftRecipeIsInRightRecipePrototypeChain = findInRecipePrototypeChain(rightRecipe, recipeCandidate => recipeCandidate === leftRecipe); // if right recipe requires left recipe, right must be after left
536
-
537
- if (leftRecipeIsInRightRecipePrototypeChain) {
538
- return -1;
539
- }
540
- }
541
-
542
- if (leftType !== rightType) {
543
- // if left is a composite, left must be after right
544
- if (leftType === "composite") {
545
- return 1;
546
- } // if right is a composite, right must be after left
547
-
548
-
549
- if (rightType === "composite") {
550
- return -1;
551
- }
552
- }
553
-
554
- const leftIndex = recipeArray.indexOf(leftRecipe);
555
- const rightIndex = recipeArray.indexOf(rightRecipe); // left was before right, don't change that
556
-
557
- if (leftIndex < rightIndex) {
558
- return -1;
559
- } // right was after left, don't change that
560
-
561
-
562
- return 1;
563
- });
564
- return recipeArrayOrdered;
565
- };
566
-
567
- // https://github.com/joliss/js-string-escape/blob/master/index.js
568
- // http://javascript.crockford.com/remedial.html
569
- const escapeString = value => {
570
- const string = String(value);
571
- let i = 0;
572
- const j = string.length;
573
- var escapedString = "";
574
-
575
- while (i < j) {
576
- const char = string[i];
577
- let escapedChar;
578
-
579
- if (char === '"' || char === "'" || char === "\\") {
580
- escapedChar = `\\${char}`;
581
- } else if (char === "\n") {
582
- escapedChar = "\\n";
583
- } else if (char === "\r") {
584
- escapedChar = "\\r";
585
- } else if (char === "\u2028") {
586
- escapedChar = "\\u2028";
587
- } else if (char === "\u2029") {
588
- escapedChar = "\\u2029";
589
- } else {
590
- escapedChar = char;
591
- }
592
-
593
- escapedString += escapedChar;
594
- i++;
595
- }
596
-
597
- return escapedString;
598
- };
599
-
600
- const uneval = (value, {
601
- functionAllowed = false,
602
- prototypeStrict = false,
603
- ignoreSymbols = false
604
- } = {}) => {
605
- const {
606
- recipeArray,
607
- mainIdentifier,
608
- valueMap
609
- } = decompose(value, {
610
- functionAllowed,
611
- prototypeStrict,
612
- ignoreSymbols
613
- });
614
- const recipeArraySorted = sortRecipe(recipeArray);
615
- let source = `(function () {
616
- var globalObject
617
- try {
618
- globalObject = Function('return this')() || (42, eval)('this');
619
- } catch(e) {
620
- globalObject = window;
621
- }
622
-
623
- function safeDefineProperty(object, propertyNameOrSymbol, descriptor) {
624
- var currentDescriptor = Object.getOwnPropertyDescriptor(object, propertyNameOrSymbol);
625
- if (currentDescriptor && !currentDescriptor.configurable) return
626
- Object.defineProperty(object, propertyNameOrSymbol, descriptor)
627
- };
628
- `;
629
- const variableNameMap = {};
630
- recipeArray.forEach((recipe, index) => {
631
- const indexSorted = recipeArraySorted.indexOf(recipe);
632
- variableNameMap[index] = `_${indexSorted}`;
633
- });
634
-
635
- const identifierToVariableName = identifier => variableNameMap[identifier];
636
-
637
- const recipeToSetupSource = recipe => {
638
- if (recipe.type === "primitive") return primitiveRecipeToSetupSource(recipe);
639
- if (recipe.type === "global-symbol") return globalSymbolRecipeToSetupSource(recipe);
640
- if (recipe.type === "global-reference") return globalReferenceRecipeToSetupSource(recipe);
641
- return compositeRecipeToSetupSource(recipe);
642
- };
643
-
644
- const primitiveRecipeToSetupSource = ({
645
- value
646
- }) => {
647
- const type = typeof value;
648
-
649
- if (type === "string") {
650
- return `"${escapeString(value)}";`;
651
- }
652
-
653
- if (type === "bigint") {
654
- return `${value.toString()}n`;
655
- }
656
-
657
- if (Object.is(value, -0)) {
658
- return "-0;";
659
- }
660
-
661
- return `${String(value)};`;
662
- };
663
-
664
- const globalSymbolRecipeToSetupSource = recipe => {
665
- return `Symbol.for("${escapeString(recipe.key)}");`;
666
- };
667
-
668
- const globalReferenceRecipeToSetupSource = recipe => {
669
- const pathSource = recipe.path.map(part => `["${escapeString(part)}"]`).join("");
670
- return `globalObject${pathSource};`;
671
- };
672
-
673
- const compositeRecipeToSetupSource = ({
674
- prototypeIdentifier,
675
- valueOfIdentifier
676
- }) => {
677
- if (prototypeIdentifier === undefined) {
678
- return identifierToVariableName(valueOfIdentifier);
679
- }
680
-
681
- const prototypeValue = valueMap[prototypeIdentifier];
682
-
683
- if (prototypeValue === null) {
684
- return `Object.create(null);`;
685
- }
686
-
687
- const prototypeConstructor = prototypeValue.constructor;
688
-
689
- if (prototypeConstructor === Object) {
690
- return `Object.create(${identifierToVariableName(prototypeIdentifier)});`;
691
- }
692
-
693
- if (valueOfIdentifier === undefined) {
694
- return `new ${prototypeConstructor.name}();`;
695
- }
696
-
697
- if (prototypeConstructor.name === "BigInt") {
698
- return `Object(${identifierToVariableName(valueOfIdentifier)})`;
699
- }
700
-
701
- return `new ${prototypeConstructor.name}(${identifierToVariableName(valueOfIdentifier)});`;
702
- };
703
-
704
- recipeArraySorted.forEach(recipe => {
705
- const recipeVariableName = identifierToVariableName(recipeArray.indexOf(recipe));
706
- source += `var ${recipeVariableName} = ${recipeToSetupSource(recipe)}
707
- `;
708
- });
709
-
710
- const recipeToMutateSource = (recipe, recipeVariableName) => {
711
- if (recipe.type === "composite") {
712
- return compositeRecipeToMutateSource(recipe, recipeVariableName);
713
- }
714
-
715
- return ``;
716
- };
717
-
718
- const compositeRecipeToMutateSource = ({
719
- propertyDescriptionArray,
720
- symbolDescriptionArray,
721
- methodDescriptionArray,
722
- extensible
723
- }, recipeVariableName) => {
724
- let mutateSource = ``;
725
- propertyDescriptionArray.forEach(({
726
- propertyNameIdentifier,
727
- propertyDescription
728
- }) => {
729
- mutateSource += generateDefinePropertySource(recipeVariableName, propertyNameIdentifier, propertyDescription);
730
- });
731
- symbolDescriptionArray.forEach(({
732
- symbolIdentifier,
733
- propertyDescription
734
- }) => {
735
- mutateSource += generateDefinePropertySource(recipeVariableName, symbolIdentifier, propertyDescription);
736
- });
737
- methodDescriptionArray.forEach(({
738
- methodNameIdentifier,
739
- callArray
740
- }) => {
741
- mutateSource += generateMethodCallSource(recipeVariableName, methodNameIdentifier, callArray);
742
- });
743
-
744
- if (!extensible) {
745
- mutateSource += generatePreventExtensionSource(recipeVariableName);
746
- }
747
-
748
- return mutateSource;
749
- };
750
-
751
- const generateDefinePropertySource = (recipeVariableName, propertyNameOrSymbolIdentifier, propertyDescription) => {
752
- const propertyOrSymbolVariableName = identifierToVariableName(propertyNameOrSymbolIdentifier);
753
- const propertyDescriptorSource = generatePropertyDescriptorSource(propertyDescription);
754
- return `safeDefineProperty(${recipeVariableName}, ${propertyOrSymbolVariableName}, ${propertyDescriptorSource});`;
755
- };
756
-
757
- const generatePropertyDescriptorSource = ({
758
- configurable,
759
- writable,
760
- enumerable,
761
- getIdentifier,
762
- setIdentifier,
763
- valueIdentifier
764
- }) => {
765
- if (valueIdentifier === undefined) {
766
- return `{
767
- configurable: ${configurable},
768
- enumerable: ${enumerable},
769
- get: ${getIdentifier === undefined ? undefined : identifierToVariableName(getIdentifier)},
770
- set: ${setIdentifier === undefined ? undefined : identifierToVariableName(setIdentifier)},
771
- }`;
772
- }
773
-
774
- return `{
775
- configurable: ${configurable},
776
- writable: ${writable},
777
- enumerable: ${enumerable},
778
- value: ${valueIdentifier === undefined ? undefined : identifierToVariableName(valueIdentifier)}
779
- }`;
780
- };
781
-
782
- const generateMethodCallSource = (recipeVariableName, methodNameIdentifier, callArray) => {
783
- let methodCallSource = ``;
784
- const methodVariableName = identifierToVariableName(methodNameIdentifier);
785
- callArray.forEach(argumentIdentifiers => {
786
- const argumentVariableNames = argumentIdentifiers.map(argumentIdentifier => identifierToVariableName(argumentIdentifier));
787
- methodCallSource += `${recipeVariableName}[${methodVariableName}](${argumentVariableNames.join(",")});`;
788
- });
789
- return methodCallSource;
790
- };
791
-
792
- const generatePreventExtensionSource = recipeVariableName => {
793
- return `Object.preventExtensions(${recipeVariableName});`;
794
- };
795
-
796
- recipeArraySorted.forEach(recipe => {
797
- const recipeVariableName = identifierToVariableName(recipeArray.indexOf(recipe));
798
- source += `${recipeToMutateSource(recipe, recipeVariableName)}`;
799
- });
800
- source += `return ${identifierToVariableName(mainIdentifier)}; })()`;
801
- return source;
802
- };
803
-
804
- export { uneval as u };