@veryfront/ext-content-mdx 0.1.1189 → 0.1.1191

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 (86) hide show
  1. package/esm/deno.d.ts +5 -0
  2. package/esm/deno.js +13 -5
  3. package/esm/src/errors/error-registry/agent.d.ts +2 -0
  4. package/esm/src/errors/error-registry/agent.d.ts.map +1 -1
  5. package/esm/src/errors/error-registry/agent.js +8 -0
  6. package/esm/src/errors/error-registry/module.d.ts +4 -0
  7. package/esm/src/errors/error-registry/module.d.ts.map +1 -1
  8. package/esm/src/errors/error-registry/module.js +16 -0
  9. package/esm/src/errors/error-registry/server.d.ts +6 -0
  10. package/esm/src/errors/error-registry/server.d.ts.map +1 -1
  11. package/esm/src/errors/error-registry/server.js +18 -0
  12. package/esm/src/errors/error-registry.d.ts +5 -0
  13. package/esm/src/errors/error-registry.d.ts.map +1 -1
  14. package/esm/src/errors/types.d.ts.map +1 -1
  15. package/esm/src/errors/types.js +5 -2
  16. package/esm/src/extensions/websocket/node-websocket-server-provider.d.ts +4 -4
  17. package/esm/src/extensions/websocket/node-websocket-server-provider.d.ts.map +1 -1
  18. package/esm/src/extensions/websocket/node-websocket-server-provider.js +4 -4
  19. package/esm/src/platform/adapters/file-snapshot-error.d.ts +7 -0
  20. package/esm/src/platform/adapters/file-snapshot-error.d.ts.map +1 -1
  21. package/esm/src/platform/adapters/file-snapshot-error.js +13 -0
  22. package/esm/src/platform/adapters/path-containment.d.ts +9 -0
  23. package/esm/src/platform/adapters/path-containment.d.ts.map +1 -0
  24. package/esm/src/platform/adapters/path-containment.js +13 -0
  25. package/esm/src/platform/adapters/runtime/shared/native-snapshot-identity.d.ts +13 -0
  26. package/esm/src/platform/adapters/runtime/shared/native-snapshot-identity.d.ts.map +1 -0
  27. package/esm/src/platform/adapters/runtime/shared/native-snapshot-identity.js +12 -0
  28. package/esm/src/platform/adapters/runtime/shared/node-filesystem-adapter.d.ts +7 -0
  29. package/esm/src/platform/adapters/runtime/shared/node-filesystem-adapter.d.ts.map +1 -1
  30. package/esm/src/platform/adapters/runtime/shared/node-filesystem-adapter.js +62 -18
  31. package/esm/src/platform/compat/error-introspection.d.ts +12 -1
  32. package/esm/src/platform/compat/error-introspection.d.ts.map +1 -1
  33. package/esm/src/platform/compat/error-introspection.js +40 -5
  34. package/esm/src/platform/compat/path/basic-operations.d.ts.map +1 -1
  35. package/esm/src/platform/compat/path/basic-operations.js +6 -2
  36. package/esm/src/platform/compat/path/portable.d.ts.map +1 -1
  37. package/esm/src/platform/compat/path/portable.js +98 -54
  38. package/esm/src/platform/compat/path/resolution.d.ts.map +1 -1
  39. package/esm/src/platform/compat/path/resolution.js +14 -5
  40. package/esm/src/platform/compat/primordials/array.d.ts +8 -0
  41. package/esm/src/platform/compat/primordials/array.d.ts.map +1 -0
  42. package/esm/src/platform/compat/primordials/array.js +33 -0
  43. package/esm/src/transforms/import-rewriter/url-builder.d.ts.map +1 -1
  44. package/esm/src/transforms/import-rewriter/url-builder.js +40 -14
  45. package/esm/src/utils/base64url.d.ts.map +1 -1
  46. package/esm/src/utils/base64url.js +10 -4
  47. package/esm/src/utils/bundle-manifest.d.ts +19 -1
  48. package/esm/src/utils/bundle-manifest.d.ts.map +1 -1
  49. package/esm/src/utils/bundle-manifest.js +124 -27
  50. package/esm/src/utils/constants/limits.d.ts +3 -1
  51. package/esm/src/utils/constants/limits.d.ts.map +1 -1
  52. package/esm/src/utils/constants/limits.js +3 -1
  53. package/esm/src/utils/hash-utils.d.ts.map +1 -1
  54. package/esm/src/utils/hash-utils.js +32 -6
  55. package/esm/src/utils/id.d.ts +16 -0
  56. package/esm/src/utils/id.d.ts.map +1 -0
  57. package/esm/src/utils/id.js +69 -0
  58. package/esm/src/utils/import-lockfile.d.ts +52 -1
  59. package/esm/src/utils/import-lockfile.d.ts.map +1 -1
  60. package/esm/src/utils/import-lockfile.js +1042 -58
  61. package/esm/src/utils/index.d.ts +1 -1
  62. package/esm/src/utils/index.d.ts.map +1 -1
  63. package/esm/src/utils/index.js +1 -1
  64. package/esm/src/utils/logger/logger.d.ts +1 -0
  65. package/esm/src/utils/logger/logger.d.ts.map +1 -1
  66. package/esm/src/utils/logger/logger.js +359 -78
  67. package/esm/src/utils/logger/redact.d.ts +4 -2
  68. package/esm/src/utils/logger/redact.d.ts.map +1 -1
  69. package/esm/src/utils/logger/redact.js +300 -112
  70. package/esm/src/utils/logger/serialization.d.ts +3 -0
  71. package/esm/src/utils/logger/serialization.d.ts.map +1 -0
  72. package/esm/src/utils/logger/serialization.js +81 -0
  73. package/esm/src/utils/memoize.d.ts +1 -1
  74. package/esm/src/utils/memoize.d.ts.map +1 -1
  75. package/esm/src/utils/memoize.js +16 -5
  76. package/esm/src/utils/path-utils.d.ts.map +1 -1
  77. package/esm/src/utils/path-utils.js +4 -2
  78. package/esm/src/utils/sleep.d.ts +8 -0
  79. package/esm/src/utils/sleep.d.ts.map +1 -1
  80. package/esm/src/utils/sleep.js +11 -2
  81. package/esm/src/utils/timer.d.ts +10 -0
  82. package/esm/src/utils/timer.d.ts.map +1 -0
  83. package/esm/src/utils/timer.js +19 -0
  84. package/esm/src/utils/version-constant.d.ts +1 -1
  85. package/esm/src/utils/version-constant.js +1 -1
  86. package/package.json +2 -2
@@ -1,26 +1,35 @@
1
1
  import { hasWindowsLikePath, portableIsAbsolute, portableNormalize, portableRelative, portableResolve, removeTrailingSeparatorsExceptRoot, runtimeUsesWindowsPaths, toPortableSeparators, } from "./portable.js";
2
2
  import { getNativePathImplementation } from "./runtime.js";
3
+ const apply = Reflect.apply;
3
4
  function usesWindowsFlavor(paths) {
4
- return runtimeUsesWindowsPaths() || paths.some(hasWindowsLikePath);
5
+ if (runtimeUsesWindowsPaths())
6
+ return true;
7
+ for (let index = 0; index < paths.length; index++) {
8
+ if (hasWindowsLikePath(paths[index]))
9
+ return true;
10
+ }
11
+ return false;
5
12
  }
6
13
  /** Resolve path segments to an absolute, normalized path. */
7
14
  export function resolve(...paths) {
8
15
  const windows = usesWindowsFlavor(paths);
9
16
  const pathApi = getNativePathImplementation(windows);
10
17
  return pathApi
11
- ? toPortableSeparators(pathApi.resolve(...paths))
18
+ ? toPortableSeparators(apply(pathApi.resolve, pathApi, paths))
12
19
  : portableResolve(paths, windows);
13
20
  }
14
21
  export function isAbsolute(path) {
15
22
  const windows = usesWindowsFlavor([path]);
16
23
  const pathApi = getNativePathImplementation(windows);
17
- return pathApi?.isAbsolute(path) ?? portableIsAbsolute(path, windows);
24
+ return pathApi
25
+ ? apply(pathApi.isAbsolute, pathApi, [path])
26
+ : portableIsAbsolute(path, windows);
18
27
  }
19
28
  export function relative(from, to) {
20
29
  const windows = usesWindowsFlavor([from, to]);
21
30
  const pathApi = getNativePathImplementation(windows);
22
31
  const result = pathApi
23
- ? toPortableSeparators(pathApi.relative(from, to))
32
+ ? toPortableSeparators(apply(pathApi.relative, pathApi, [from, to]))
24
33
  : portableRelative(from, to, windows);
25
34
  return result || ".";
26
35
  }
@@ -28,7 +37,7 @@ export function normalize(path) {
28
37
  const windows = usesWindowsFlavor([path]);
29
38
  const pathApi = getNativePathImplementation(windows);
30
39
  const normalized = pathApi
31
- ? toPortableSeparators(pathApi.normalize(path))
40
+ ? toPortableSeparators(apply(pathApi.normalize, pathApi, [path]))
32
41
  : portableNormalize(path, windows);
33
42
  // The established Veryfront facade contract returns canonical paths without
34
43
  // a trailing separator, except for filesystem roots. Enforce that
@@ -0,0 +1,8 @@
1
+ export declare function primordialArrayAt<T>(values: readonly T[], index: number): T | undefined;
2
+ export declare function primordialArrayFilter<T>(values: readonly T[], predicate: (value: T, index: number, array: readonly T[]) => unknown): T[];
3
+ export declare function primordialArrayJoin(values: readonly unknown[], separator: string): string;
4
+ export declare function primordialArrayMap<T, U>(values: readonly T[], callback: (value: T, index: number, array: readonly T[]) => U): U[];
5
+ export declare function primordialArrayPop<T>(values: T[]): T | undefined;
6
+ export declare function primordialArrayPush<T>(values: T[], value: T): void;
7
+ export declare function primordialArraySort<T>(values: T[], compare: (left: T, right: T) => number): T[];
8
+ //# sourceMappingURL=array.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"array.d.ts","sourceRoot":"","sources":["../../../../../src/src/platform/compat/primordials/array.ts"],"names":[],"mappings":"AAaA,wBAAgB,iBAAiB,CAAC,CAAC,EACjC,MAAM,EAAE,SAAS,CAAC,EAAE,EACpB,KAAK,EAAE,MAAM,GACZ,CAAC,GAAG,SAAS,CAEf;AAED,wBAAgB,qBAAqB,CAAC,CAAC,EACrC,MAAM,EAAE,SAAS,CAAC,EAAE,EACpB,SAAS,EAAE,CAAC,KAAK,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,SAAS,CAAC,EAAE,KAAK,OAAO,GACnE,CAAC,EAAE,CAEL;AAED,wBAAgB,mBAAmB,CACjC,MAAM,EAAE,SAAS,OAAO,EAAE,EAC1B,SAAS,EAAE,MAAM,GAChB,MAAM,CAER;AAED,wBAAgB,kBAAkB,CAAC,CAAC,EAAE,CAAC,EACrC,MAAM,EAAE,SAAS,CAAC,EAAE,EACpB,QAAQ,EAAE,CAAC,KAAK,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,SAAS,CAAC,EAAE,KAAK,CAAC,GAC5D,CAAC,EAAE,CAEL;AAED,wBAAgB,kBAAkB,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,GAAG,CAAC,GAAG,SAAS,CAEhE;AAED,wBAAgB,mBAAmB,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,EAAE,KAAK,EAAE,CAAC,GAAG,IAAI,CAElE;AAED,wBAAgB,mBAAmB,CAAC,CAAC,EACnC,MAAM,EAAE,CAAC,EAAE,EACX,OAAO,EAAE,CAAC,IAAI,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,KAAK,MAAM,GACrC,CAAC,EAAE,CAEL"}
@@ -0,0 +1,33 @@
1
+ // Capture shared array intrinsics once, before project code can replace mutable
2
+ // prototype methods in a long-lived runtime. Keep this module dependency-free so
3
+ // low-level compatibility code and higher framework layers can use the same
4
+ // trusted operations without introducing an import cycle.
5
+ const ArrayPrototypeAt = Array.prototype.at;
6
+ const ArrayPrototypeFilter = Array.prototype.filter;
7
+ const ArrayPrototypeJoin = Array.prototype.join;
8
+ const ArrayPrototypeMap = Array.prototype.map;
9
+ const ArrayPrototypePop = Array.prototype.pop;
10
+ const ArrayPrototypePush = Array.prototype.push;
11
+ const ArrayPrototypeSort = Array.prototype.sort;
12
+ const ReflectApply = Reflect.apply;
13
+ export function primordialArrayAt(values, index) {
14
+ return ReflectApply(ArrayPrototypeAt, values, [index]);
15
+ }
16
+ export function primordialArrayFilter(values, predicate) {
17
+ return ReflectApply(ArrayPrototypeFilter, values, [predicate]);
18
+ }
19
+ export function primordialArrayJoin(values, separator) {
20
+ return ReflectApply(ArrayPrototypeJoin, values, [separator]);
21
+ }
22
+ export function primordialArrayMap(values, callback) {
23
+ return ReflectApply(ArrayPrototypeMap, values, [callback]);
24
+ }
25
+ export function primordialArrayPop(values) {
26
+ return ReflectApply(ArrayPrototypePop, values, []);
27
+ }
28
+ export function primordialArrayPush(values, value) {
29
+ ReflectApply(ArrayPrototypePush, values, [value]);
30
+ }
31
+ export function primordialArraySort(values, compare) {
32
+ return ReflectApply(ArrayPrototypeSort, values, [compare]);
33
+ }
@@ -1 +1 @@
1
- {"version":3,"file":"url-builder.d.ts","sourceRoot":"","sources":["../../../../src/src/transforms/import-rewriter/url-builder.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH;;;;;;;GAOG;AACH,eAAO,MAAM,qBAAqB,WAAW,CAAC;AAE9C,2BAA2B;AAC3B,eAAO,MAAM,gBAAgB,UAAU,CAAC;AAExC,kEAAkE;AAClE,eAAO,MAAM,eAAe,UAAU,CAAC;AAEvC,KAAK,YAAY,GAAG;IAClB,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;IACpB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAC/B,CAAC;AAEF;;;;;;;GAOG;AACH,wBAAgB,aAAa,CAC3B,GAAG,EAAE,MAAM,EACX,OAAO,CAAC,EAAE,MAAM,EAChB,OAAO,CAAC,EAAE,MAAM,EAChB,OAAO,CAAC,EAAE,YAAY,GACrB,MAAM,CAqBR;AAED;;;GAGG;AACH,wBAAgB,aAAa,CAC3B,GAAG,EAAE,OAAO,GAAG,WAAW,EAC1B,OAAO,EAAE,MAAM,EACf,OAAO,CAAC,EAAE,MAAM,EAChB,QAAQ,UAAQ,GACf,MAAM,CAKR;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAWzE;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAI1E;AAED;;;GAGG;AACH,wBAAgB,0BAA0B,CACxC,GAAG,EAAE,MAAM,EACX,yBAAyB,CAAC,EAAE,MAAM,GACjC,MAAM,CAcR;AAeD;;;;;GAKG;AACH,wBAAgB,8BAA8B,CAC5C,GAAG,EAAE,MAAM,EACX,yBAAyB,CAAC,EAAE,MAAM,GACjC,MAAM,CA4CR;AAED;;;GAGG;AACH,wBAAgB,wCAAwC,CACtD,GAAG,EAAE,MAAM,EACX,yBAAyB,CAAC,EAAE,MAAM,EAClC,kBAAkB,CAAC,EAAE,MAAM,GAC1B,MAAM,CA8BR;AAED;;;GAGG;AACH,wBAAgB,uCAAuC,CACrD,GAAG,EAAE,MAAM,EACX,yBAAyB,CAAC,EAAE,MAAM,EAClC,kBAAkB,CAAC,EAAE,MAAM,GAC1B,MAAM,CAwBR;AAED,MAAM,WAAW,8BAA8B;IAC7C,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,OAAO,CAAC;IACf,SAAS,EAAE,OAAO,CAAC;CACpB;AAED;;;;GAIG;AACH,wBAAgB,+BAA+B,CAC7C,QAAQ,EAAE,MAAM,GACf,8BAA8B,CA4ChC;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAClC,WAAW,EAAE,MAAM,EACnB,OAAO,EAAE,MAAM,GAAG,IAAI,EACtB,IAAI,EAAE,MAAM,GACX,MAAM,CAIR;AAED;;GAEG;AACH,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAG5D;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE;IAAE,eAAe,CAAC,EAAE,OAAO,CAAA;CAAE,GAAG,MAAM,CAGhG;AAED;;GAEG;AACH,wBAAgB,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAE/C;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,GAAG,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,GAAG,MAAM,CAgDtE"}
1
+ {"version":3,"file":"url-builder.d.ts","sourceRoot":"","sources":["../../../../src/src/transforms/import-rewriter/url-builder.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAOH;;;;;;;GAOG;AACH,eAAO,MAAM,qBAAqB,WAAW,CAAC;AAE9C,2BAA2B;AAC3B,eAAO,MAAM,gBAAgB,UAAU,CAAC;AAExC,kEAAkE;AAClE,eAAO,MAAM,eAAe,UAAU,CAAC;AAEvC,KAAK,YAAY,GAAG;IAClB,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;IACpB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAC/B,CAAC;AA0BF;;;;;;;GAOG;AACH,wBAAgB,aAAa,CAC3B,GAAG,EAAE,MAAM,EACX,OAAO,CAAC,EAAE,MAAM,EAChB,OAAO,CAAC,EAAE,MAAM,EAChB,OAAO,CAAC,EAAE,YAAY,GACrB,MAAM,CAQR;AAgBD;;;GAGG;AACH,wBAAgB,aAAa,CAC3B,GAAG,EAAE,OAAO,GAAG,WAAW,EAC1B,OAAO,EAAE,MAAM,EACf,OAAO,CAAC,EAAE,MAAM,EAChB,QAAQ,UAAQ,GACf,MAAM,CAKR;AAYD;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAazE;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAI1E;AAED;;;GAGG;AACH,wBAAgB,0BAA0B,CACxC,GAAG,EAAE,MAAM,EACX,yBAAyB,CAAC,EAAE,MAAM,GACjC,MAAM,CAcR;AAeD;;;;;GAKG;AACH,wBAAgB,8BAA8B,CAC5C,GAAG,EAAE,MAAM,EACX,yBAAyB,CAAC,EAAE,MAAM,GACjC,MAAM,CA4CR;AAED;;;GAGG;AACH,wBAAgB,wCAAwC,CACtD,GAAG,EAAE,MAAM,EACX,yBAAyB,CAAC,EAAE,MAAM,EAClC,kBAAkB,CAAC,EAAE,MAAM,GAC1B,MAAM,CA8BR;AAED;;;GAGG;AACH,wBAAgB,uCAAuC,CACrD,GAAG,EAAE,MAAM,EACX,yBAAyB,CAAC,EAAE,MAAM,EAClC,kBAAkB,CAAC,EAAE,MAAM,GAC1B,MAAM,CAwBR;AAED,MAAM,WAAW,8BAA8B;IAC7C,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,OAAO,CAAC;IACf,SAAS,EAAE,OAAO,CAAC;CACpB;AAED;;;;GAIG;AACH,wBAAgB,+BAA+B,CAC7C,QAAQ,EAAE,MAAM,GACf,8BAA8B,CA4ChC;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAClC,WAAW,EAAE,MAAM,EACnB,OAAO,EAAE,MAAM,GAAG,IAAI,EACtB,IAAI,EAAE,MAAM,GACX,MAAM,CAIR;AAED;;GAEG;AACH,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAG5D;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE;IAAE,eAAe,CAAC,EAAE,OAAO,CAAA;CAAE,GAAG,MAAM,CAGhG;AAED;;GAEG;AACH,wBAAgB,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAE/C;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,GAAG,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,GAAG,MAAM,CAgDtE"}
@@ -4,6 +4,7 @@
4
4
  * Single source of truth for all URL generation.
5
5
  * Ensures consistent URLs across SSR and browser for hydration parity.
6
6
  */
7
+ import { primordialArrayJoin as arrayJoin, primordialArrayPush as arrayPush, } from "../../platform/compat/primordials/array.js";
7
8
  /**
8
9
  * Default React version - used when not specified.
9
10
  *
@@ -17,6 +18,24 @@ export const DEFAULT_REACT_VERSION = "19.2.4";
17
18
  export const TAILWIND_VERSION = "4.1.8";
18
19
  /** csstype version - must match deno.json for type consistency */
19
20
  export const CSSTYPE_VERSION = "3.2.3";
21
+ const ObjectEntries = Object.entries;
22
+ function buildEsmShParams(options) {
23
+ const params = [];
24
+ if (options?.external?.length) {
25
+ arrayPush(params, `external=${arrayJoin(options.external, ",")}`);
26
+ }
27
+ arrayPush(params, `target=${options?.target ?? "es2022"}`);
28
+ if (options?.deps) {
29
+ const deps = [];
30
+ const entries = ObjectEntries(options.deps);
31
+ for (let index = 0; index < entries.length; index++) {
32
+ const [key, value] = entries[index];
33
+ arrayPush(deps, `${key}@${value}`);
34
+ }
35
+ arrayPush(params, `deps=${arrayJoin(deps, ",")}`);
36
+ }
37
+ return params;
38
+ }
20
39
  /**
21
40
  * Build esm.sh URL with proper configuration.
22
41
  *
@@ -26,22 +45,21 @@ export const CSSTYPE_VERSION = "3.2.3";
26
45
  * @param options - URL options
27
46
  */
28
47
  export function buildEsmShUrl(pkg, version, subpath, options) {
29
- const params = [];
30
- if (options?.external?.length) {
31
- params.push(`external=${options.external.join(",")}`);
32
- }
33
- params.push(`target=${options?.target ?? "es2022"}`);
34
- if (options?.deps) {
35
- const depsStr = Object.entries(options.deps)
36
- .map(([k, v]) => `${k}@${v}`)
37
- .join(",");
38
- params.push(`deps=${depsStr}`);
39
- }
48
+ const params = buildEsmShParams(options);
40
49
  const versionStr = version ? `@${version}` : "";
41
50
  const pathStr = subpath ?? "";
42
- const queryStr = params.length ? `?${params.join("&")}` : "";
51
+ const queryStr = params.length ? `?${arrayJoin(params, "&")}` : "";
43
52
  return `https://esm.sh/${pkg}${versionStr}${pathStr}${queryStr}`;
44
53
  }
54
+ /**
55
+ * Build an esm.sh package-prefix URL. esm.sh's `&option/` form keeps the
56
+ * trailing slash required by the import-map prefix-matching algorithm.
57
+ */
58
+ function buildEsmShPrefixUrl(pkg, version, options) {
59
+ const params = buildEsmShParams(options);
60
+ const optionStr = params.length ? `&${arrayJoin(params, "&")}` : "";
61
+ return `https://esm.sh/${pkg}@${version}${optionStr}/`;
62
+ }
45
63
  /**
46
64
  * Build React esm.sh URL.
47
65
  * Uses deps=csstype for type consistency.
@@ -52,6 +70,12 @@ export function buildReactUrl(pkg, version, subpath, external = false) {
52
70
  deps: { csstype: CSSTYPE_VERSION },
53
71
  });
54
72
  }
73
+ function buildReactPrefixUrl(pkg, version) {
74
+ return buildEsmShPrefixUrl(pkg, version, {
75
+ external: ["react"],
76
+ deps: { csstype: CSSTYPE_VERSION },
77
+ });
78
+ }
55
79
  /**
56
80
  * Get complete React import map for a specific version.
57
81
  */
@@ -63,8 +87,10 @@ export function getReactImportMap(version) {
63
87
  "react-dom/server": buildReactUrl("react-dom", version, "/server", true),
64
88
  "react/jsx-runtime": buildReactUrl("react", version, "/jsx-runtime", true),
65
89
  "react/jsx-dev-runtime": buildReactUrl("react", version, "/jsx-dev-runtime", true),
66
- // Prefix match for any react/* subpath imports
67
- "react/": buildReactUrl("react", version, "/", true),
90
+ // Prefix matches cover future package exports without allowing a project
91
+ // import map to redirect React or ReactDOM subpaths.
92
+ "react/": buildReactPrefixUrl("react", version),
93
+ "react-dom/": buildReactPrefixUrl("react-dom", version),
68
94
  };
69
95
  }
70
96
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"base64url.d.ts","sourceRoot":"","sources":["../../../src/src/utils/base64url.ts"],"names":[],"mappings":"AAYA;;;;;;GAMG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAelD;AAED,2CAA2C;AAC3C,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,UAAU,GAAG,MAAM,CAa3D;AAED,6CAA6C;AAC7C,wBAAgB,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAErD;AAED,8CAA8C;AAC9C,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,UAAU,GAAG,MAAM,CAE9D"}
1
+ {"version":3,"file":"base64url.d.ts","sourceRoot":"","sources":["../../../src/src/utils/base64url.ts"],"names":[],"mappings":"AAYA;;;;;;GAMG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAelD;AAED,2CAA2C;AAC3C,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,UAAU,GAAG,MAAM,CAoB3D;AAED,6CAA6C;AAC7C,wBAAgB,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAErD;AAED,8CAA8C;AAC9C,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,UAAU,GAAG,MAAM,CAE9D"}
@@ -36,10 +36,16 @@ export function encodeBase64Bytes(bytes) {
36
36
  if (bufferCtor)
37
37
  return bufferCtor.from(bytes).toString("base64");
38
38
  if (typeof globalThis.btoa === "function") {
39
- let binary = "";
40
- for (const byte of bytes)
41
- binary += String.fromCharCode(byte);
42
- return globalThis.btoa(binary);
39
+ // Bound the peak temporary binary string to 24 KiB. The chunk size is
40
+ // divisible by three, so only the final base64 chunk can contain padding.
41
+ const chunkSize = 24 * 1024;
42
+ const encodedChunks = [];
43
+ for (let offset = 0; offset < bytes.length; offset += chunkSize) {
44
+ const end = Math.min(offset + chunkSize, bytes.length);
45
+ const binaryChunk = String.fromCharCode(...bytes.subarray(offset, end));
46
+ encodedChunks.push(globalThis.btoa(binaryChunk));
47
+ }
48
+ return encodedChunks.join("");
43
49
  }
44
50
  throw new Error("Base64 encoding is not supported in this runtime");
45
51
  }
@@ -41,11 +41,14 @@ export interface BundleManifestStore {
41
41
  isAvailable(): Promise<boolean>;
42
42
  getStats(): Promise<BundleManifestStats>;
43
43
  }
44
+ /** Minimum interval between full expired-metadata sweeps (amortized on writes). */
45
+ export declare const BUNDLE_MANIFEST_SWEEP_INTERVAL_MS = 30000;
44
46
  export declare class InMemoryBundleManifestStore implements BundleManifestStore {
45
47
  private metadata;
46
48
  private code;
47
49
  private sourceIndex;
48
- private getIfNotExpired;
50
+ private codeReferences;
51
+ private lastExpiredSweepAt;
49
52
  getBundleMetadata(key: string): Promise<BundleMetadata | undefined>;
50
53
  setBundleMetadata(key: string, metadata: BundleMetadata, ttlMs?: number): Promise<void>;
51
54
  getBundleCode(hash: string): Promise<BundleCode | undefined>;
@@ -55,6 +58,21 @@ export declare class InMemoryBundleManifestStore implements BundleManifestStore
55
58
  clear(): Promise<void>;
56
59
  isAvailable(): Promise<boolean>;
57
60
  getStats(): Promise<BundleManifestStats>;
61
+ private addCodeReference;
62
+ /**
63
+ * Drop expired metadata entries referencing one code hash so the reference
64
+ * check in getBundleCode stays trustworthy without a full-map sweep.
65
+ */
66
+ private pruneExpiredReferencesTo;
67
+ /**
68
+ * Full expired-metadata sweep, amortized: runs on writes at most once per
69
+ * BUNDLE_MANIFEST_SWEEP_INTERVAL_MS so unread expired entries cannot pin
70
+ * memory forever while per-render reads stay off the O(all-metadata) path.
71
+ */
72
+ private sweepExpiredMetadataIfDue;
73
+ private removeCodeReference;
74
+ private removeMetadata;
75
+ private removeSourceReference;
58
76
  }
59
77
  export declare function setBundleManifestStore(store: BundleManifestStore): void;
60
78
  /** Return bundle manifest store. */
@@ -1 +1 @@
1
- {"version":3,"file":"bundle-manifest.d.ts","sourceRoot":"","sources":["../../../src/src/utils/bundle-manifest.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"bundle-manifest.d.ts","sourceRoot":"","sources":["../../../src/src/utils/bundle-manifest.ts"],"names":[],"mappings":"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"}
@@ -1,55 +1,79 @@
1
1
  import { serverLogger } from "./logger/index.js";
2
2
  const logger = serverLogger.component("bundle-manifest");
3
+ /** Minimum interval between full expired-metadata sweeps (amortized on writes). */
4
+ export const BUNDLE_MANIFEST_SWEEP_INTERVAL_MS = 30_000;
3
5
  export class InMemoryBundleManifestStore {
4
6
  metadata = new Map();
5
7
  code = new Map();
6
8
  sourceIndex = new Map();
7
- getIfNotExpired(map, key) {
8
- const entry = map.get(key);
9
+ // codeHash → metadata keys holding a reference. Each key holds at most one
10
+ // reference per hash, so set size is the reference count and the members
11
+ // let reads prune only the metadata entries relevant to one hash.
12
+ codeReferences = new Map();
13
+ lastExpiredSweepAt = Date.now();
14
+ async getBundleMetadata(key) {
15
+ const entry = this.metadata.get(key);
9
16
  if (!entry)
10
17
  return undefined;
11
- if (entry.expiry != null && Date.now() > entry.expiry) {
12
- map.delete(key);
18
+ if (entry.expiry != null && Date.now() >= entry.expiry) {
19
+ this.removeMetadata(key);
13
20
  return undefined;
14
21
  }
15
- return entry.value;
16
- }
17
- async getBundleMetadata(key) {
18
- return this.getIfNotExpired(this.metadata, key);
22
+ return structuredClone(entry.value);
19
23
  }
20
24
  async setBundleMetadata(key, metadata, ttlMs) {
25
+ this.sweepExpiredMetadataIfDue();
21
26
  const expiry = ttlMs != null ? Date.now() + ttlMs : undefined;
22
- this.metadata.set(key, { value: metadata, expiry });
23
- const keys = this.sourceIndex.get(metadata.source) ?? new Set();
27
+ const snapshot = structuredClone(metadata);
28
+ const previous = this.metadata.get(key)?.value;
29
+ if (!previous) {
30
+ this.addCodeReference(snapshot.codeHash, key);
31
+ }
32
+ else if (previous.codeHash !== snapshot.codeHash) {
33
+ this.removeCodeReference(previous.codeHash, key);
34
+ this.addCodeReference(snapshot.codeHash, key);
35
+ }
36
+ if (previous && previous.source !== snapshot.source) {
37
+ this.removeSourceReference(key, previous.source);
38
+ }
39
+ this.metadata.set(key, { value: snapshot, expiry });
40
+ const keys = this.sourceIndex.get(snapshot.source) ?? new Set();
24
41
  keys.add(key);
25
- this.sourceIndex.set(metadata.source, keys);
42
+ this.sourceIndex.set(snapshot.source, keys);
26
43
  }
27
44
  async getBundleCode(hash) {
28
- return this.getIfNotExpired(this.code, hash);
45
+ // Only the metadata entries referencing this hash decide its liveness, so
46
+ // prune those lazily instead of sweeping the entire metadata map on every
47
+ // per-render read. Full sweeps are amortized onto writes.
48
+ this.pruneExpiredReferencesTo(hash);
49
+ const entry = this.code.get(hash);
50
+ if (!entry)
51
+ return undefined;
52
+ // Metadata references own code liveness. A shorter code TTL must not turn
53
+ // a still-valid manifest into a pointer to a missing content blob.
54
+ if (entry.expiry != null &&
55
+ Date.now() >= entry.expiry &&
56
+ !this.codeReferences.has(hash)) {
57
+ this.code.delete(hash);
58
+ return undefined;
59
+ }
60
+ return structuredClone(entry.value);
29
61
  }
30
62
  async setBundleCode(hash, code, ttlMs) {
63
+ this.sweepExpiredMetadataIfDue();
31
64
  const expiry = ttlMs != null ? Date.now() + ttlMs : undefined;
32
- this.code.set(hash, { value: code, expiry });
65
+ this.code.set(hash, { value: structuredClone(code), expiry });
33
66
  }
34
67
  async deleteBundle(key) {
35
- const metadata = await this.getBundleMetadata(key);
36
- this.metadata.delete(key);
37
- if (!metadata)
38
- return;
39
- this.code.delete(metadata.codeHash);
40
- const sourceKeys = this.sourceIndex.get(metadata.source);
41
- if (!sourceKeys)
42
- return;
43
- sourceKeys.delete(key);
44
- if (sourceKeys.size === 0)
45
- this.sourceIndex.delete(metadata.source);
68
+ this.removeMetadata(key);
46
69
  }
47
70
  async invalidateSource(source) {
48
71
  const keys = this.sourceIndex.get(source);
49
72
  if (!keys)
50
73
  return 0;
51
74
  const keysArray = [...keys];
52
- await Promise.all(keysArray.map((key) => this.deleteBundle(key)));
75
+ for (const key of keysArray)
76
+ this.removeMetadata(key);
53
77
  this.sourceIndex.delete(source);
54
78
  return keysArray.length;
55
79
  }
@@ -57,15 +81,23 @@ export class InMemoryBundleManifestStore {
57
81
  this.metadata.clear();
58
82
  this.code.clear();
59
83
  this.sourceIndex.clear();
84
+ this.codeReferences.clear();
60
85
  }
61
86
  async isAvailable() {
62
87
  return true;
63
88
  }
64
89
  async getStats() {
90
+ // Non-mutating expiry view: expired entries are excluded from the
91
+ // aggregate without paying a pruning sweep on this read path.
92
+ const now = Date.now();
93
+ let totalBundles = 0;
65
94
  let totalSize = 0;
66
95
  let oldestBundle;
67
96
  let newestBundle;
68
- for (const { value } of this.metadata.values()) {
97
+ for (const { value, expiry } of this.metadata.values()) {
98
+ if (expiry != null && now >= expiry)
99
+ continue;
100
+ totalBundles++;
69
101
  totalSize += value.size;
70
102
  oldestBundle = oldestBundle == null
71
103
  ? value.compiledAt
@@ -75,12 +107,77 @@ export class InMemoryBundleManifestStore {
75
107
  : Math.max(newestBundle, value.compiledAt);
76
108
  }
77
109
  return {
78
- totalBundles: this.metadata.size,
110
+ totalBundles,
79
111
  totalSize,
80
112
  oldestBundle,
81
113
  newestBundle,
82
114
  };
83
115
  }
116
+ addCodeReference(codeHash, key) {
117
+ const refs = this.codeReferences.get(codeHash) ?? new Set();
118
+ refs.add(key);
119
+ this.codeReferences.set(codeHash, refs);
120
+ }
121
+ /**
122
+ * Drop expired metadata entries referencing one code hash so the reference
123
+ * check in getBundleCode stays trustworthy without a full-map sweep.
124
+ */
125
+ pruneExpiredReferencesTo(hash, now = Date.now()) {
126
+ const refs = this.codeReferences.get(hash);
127
+ if (!refs)
128
+ return;
129
+ for (const key of [...refs]) {
130
+ const entry = this.metadata.get(key);
131
+ if (!entry) {
132
+ // Defensive: a reference without metadata is stale bookkeeping.
133
+ this.removeCodeReference(hash, key);
134
+ continue;
135
+ }
136
+ if (entry.expiry != null && now >= entry.expiry)
137
+ this.removeMetadata(key);
138
+ }
139
+ }
140
+ /**
141
+ * Full expired-metadata sweep, amortized: runs on writes at most once per
142
+ * BUNDLE_MANIFEST_SWEEP_INTERVAL_MS so unread expired entries cannot pin
143
+ * memory forever while per-render reads stay off the O(all-metadata) path.
144
+ */
145
+ sweepExpiredMetadataIfDue(now = Date.now()) {
146
+ if (now - this.lastExpiredSweepAt < BUNDLE_MANIFEST_SWEEP_INTERVAL_MS)
147
+ return;
148
+ this.lastExpiredSweepAt = now;
149
+ for (const [key, entry] of this.metadata) {
150
+ if (entry.expiry != null && now >= entry.expiry)
151
+ this.removeMetadata(key);
152
+ }
153
+ }
154
+ removeCodeReference(codeHash, key) {
155
+ const refs = this.codeReferences.get(codeHash);
156
+ if (refs) {
157
+ refs.delete(key);
158
+ if (refs.size > 0)
159
+ return;
160
+ this.codeReferences.delete(codeHash);
161
+ }
162
+ this.code.delete(codeHash);
163
+ }
164
+ removeMetadata(key) {
165
+ const metadata = this.metadata.get(key)?.value;
166
+ if (!metadata)
167
+ return undefined;
168
+ this.metadata.delete(key);
169
+ this.removeSourceReference(key, metadata.source);
170
+ this.removeCodeReference(metadata.codeHash, key);
171
+ return metadata;
172
+ }
173
+ removeSourceReference(key, source) {
174
+ const sourceKeys = this.sourceIndex.get(source);
175
+ if (!sourceKeys)
176
+ return;
177
+ sourceKeys.delete(key);
178
+ if (sourceKeys.size === 0)
179
+ this.sourceIndex.delete(source);
180
+ }
84
181
  }
85
182
  let manifestStore = new InMemoryBundleManifestStore();
86
183
  export function setBundleManifestStore(store) {
@@ -21,10 +21,12 @@ export declare const HANDLER_CACHE_MAX_ENTRIES = 256;
21
21
  /** Maximum key length accepted by the shared in-memory cache adapter. */
22
22
  export declare const MAX_CACHE_KEY_CHARACTERS = 16384;
23
23
  export declare const MAX_PATH_LENGTH_CHARS = 4096;
24
+ /** Maximum number of path segments admitted by framework route resolvers. */
25
+ export declare const MAX_ROUTE_SEGMENTS = 64;
24
26
  export declare const MAX_PORT_NUMBER = 65535;
25
27
  export declare const MIN_PORT_NUMBER = 1;
26
28
  export declare const MAX_URL_LENGTH_FOR_VALIDATION = 2048;
27
- /******** Batch limits ********/
29
+ /** Maximum batch size. */
28
30
  export declare const MAX_BATCH_SIZE = 100;
29
31
  /** Largest delay supported consistently by JavaScript timer implementations. */
30
32
  export declare const MAX_TIMER_DELAY_MS = 2147483647;
@@ -1 +1 @@
1
- {"version":3,"file":"limits.d.ts","sourceRoot":"","sources":["../../../../src/src/utils/constants/limits.ts"],"names":[],"mappings":"AAAA,kCAAkC;AAClC,eAAO,MAAM,yBAAyB,OAAO,CAAC;AAC9C,eAAO,MAAM,4BAA4B,MAAM,CAAC;AAChD,eAAO,MAAM,8BAA8B,MAAM,CAAC;AAClD,eAAO,MAAM,6BAA6B,MAAM,CAAC;AACjD,eAAO,MAAM,qBAAqB,MAAM,CAAC;AAEzC,gCAAgC;AAChC,eAAO,MAAM,oBAAoB,OAAO,CAAC;AACzC,eAAO,MAAM,8BAA8B,QAAQ,CAAC;AACpD,eAAO,MAAM,mBAAmB,MAAM,CAAC;AACvC,eAAO,MAAM,kBAAkB,MAAM,CAAC;AAEtC,eAAO,MAAM,sBAAsB,KAAK,CAAC;AACzC,eAAO,MAAM,mBAAmB,MAAM,CAAC;AAEvC,qCAAqC;AACrC,eAAO,MAAM,uBAAuB,KAAK,CAAC;AAC1C,eAAO,MAAM,wBAAwB,MAAM,CAAC;AAC5C,eAAO,MAAM,uBAAuB,MAAM,CAAC;AAC3C,eAAO,MAAM,wBAAwB,OAAO,CAAC;AAC7C,eAAO,MAAM,2BAA2B,MAAM,CAAC;AAC/C,eAAO,MAAM,yBAAyB,MAAM,CAAC;AAC7C,yEAAyE;AACzE,eAAO,MAAM,wBAAwB,QAAS,CAAC;AAE/C,eAAO,MAAM,qBAAqB,OAAO,CAAC;AAC1C,eAAO,MAAM,eAAe,QAAQ,CAAC;AACrC,eAAO,MAAM,eAAe,IAAI,CAAC;AACjC,eAAO,MAAM,6BAA6B,OAAO,CAAC;AAElD,gCAAgC;AAChC,eAAO,MAAM,cAAc,MAAM,CAAC;AAElC,gFAAgF;AAChF,eAAO,MAAM,kBAAkB,aAAgB,CAAC"}
1
+ {"version":3,"file":"limits.d.ts","sourceRoot":"","sources":["../../../../src/src/utils/constants/limits.ts"],"names":[],"mappings":"AAAA,kCAAkC;AAClC,eAAO,MAAM,yBAAyB,OAAO,CAAC;AAC9C,eAAO,MAAM,4BAA4B,MAAM,CAAC;AAChD,eAAO,MAAM,8BAA8B,MAAM,CAAC;AAClD,eAAO,MAAM,6BAA6B,MAAM,CAAC;AACjD,eAAO,MAAM,qBAAqB,MAAM,CAAC;AAEzC,gCAAgC;AAChC,eAAO,MAAM,oBAAoB,OAAO,CAAC;AACzC,eAAO,MAAM,8BAA8B,QAAQ,CAAC;AACpD,eAAO,MAAM,mBAAmB,MAAM,CAAC;AACvC,eAAO,MAAM,kBAAkB,MAAM,CAAC;AAEtC,eAAO,MAAM,sBAAsB,KAAK,CAAC;AACzC,eAAO,MAAM,mBAAmB,MAAM,CAAC;AAEvC,qCAAqC;AACrC,eAAO,MAAM,uBAAuB,KAAK,CAAC;AAC1C,eAAO,MAAM,wBAAwB,MAAM,CAAC;AAC5C,eAAO,MAAM,uBAAuB,MAAM,CAAC;AAC3C,eAAO,MAAM,wBAAwB,OAAO,CAAC;AAC7C,eAAO,MAAM,2BAA2B,MAAM,CAAC;AAC/C,eAAO,MAAM,yBAAyB,MAAM,CAAC;AAC7C,yEAAyE;AACzE,eAAO,MAAM,wBAAwB,QAAS,CAAC;AAE/C,eAAO,MAAM,qBAAqB,OAAO,CAAC;AAC1C,6EAA6E;AAC7E,eAAO,MAAM,kBAAkB,KAAK,CAAC;AACrC,eAAO,MAAM,eAAe,QAAQ,CAAC;AACrC,eAAO,MAAM,eAAe,IAAI,CAAC;AACjC,eAAO,MAAM,6BAA6B,OAAO,CAAC;AAElD,0BAA0B;AAC1B,eAAO,MAAM,cAAc,MAAM,CAAC;AAElC,gFAAgF;AAChF,eAAO,MAAM,kBAAkB,aAAgB,CAAC"}
@@ -21,10 +21,12 @@ export const HANDLER_CACHE_MAX_ENTRIES = 256;
21
21
  /** Maximum key length accepted by the shared in-memory cache adapter. */
22
22
  export const MAX_CACHE_KEY_CHARACTERS = 16_384;
23
23
  export const MAX_PATH_LENGTH_CHARS = 4096;
24
+ /** Maximum number of path segments admitted by framework route resolvers. */
25
+ export const MAX_ROUTE_SEGMENTS = 64;
24
26
  export const MAX_PORT_NUMBER = 65535;
25
27
  export const MIN_PORT_NUMBER = 1;
26
28
  export const MAX_URL_LENGTH_FOR_VALIDATION = 2048;
27
- /******** Batch limits ********/
29
+ /** Maximum batch size. */
28
30
  export const MAX_BATCH_SIZE = 100;
29
31
  /** Largest delay supported consistently by JavaScript timer implementations. */
30
32
  export const MAX_TIMER_DELAY_MS = 2_147_483_647;
@@ -1 +1 @@
1
- {"version":3,"file":"hash-utils.d.ts","sourceRoot":"","sources":["../../../src/src/utils/hash-utils.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,OAAO,MAAM,qBAAqB,CAAC;AAW/C,kEAAkE;AAClE,wBAAsB,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAGlE;AAED,6DAA6D;AAC7D,wBAAsB,gBAAgB,CAAC,KAAK,EAAE,OAAO,CAAC,YAAY,GAAG,OAAO,CAAC,MAAM,CAAC,CAEnF;AACD,uDAAuD;AACvD,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,yBAAyB;AACzB,wBAAgB,eAAe,CAAC,IAAI,EAAE,UAAU,GAAG,OAAO,CAAC,MAAM,CAAC,CAEjE;AAED,0BAA0B;AAC1B,wBAAgB,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAS9C;AAED,+DAA+D;AAC/D,wBAAgB,WAAW,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAE/C;AAED,yBAAyB;AACzB,wBAAsB,SAAS,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAGhE;AAED,mDAAmD;AACnD,wBAAgB,SAAS,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAS/C"}
1
+ {"version":3,"file":"hash-utils.d.ts","sourceRoot":"","sources":["../../../src/src/utils/hash-utils.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,OAAO,MAAM,qBAAqB,CAAC;AA0C/C,kEAAkE;AAClE,wBAAsB,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAalE;AAED,6DAA6D;AAC7D,wBAAsB,gBAAgB,CAAC,KAAK,EAAE,OAAO,CAAC,YAAY,GAAG,OAAO,CAAC,MAAM,CAAC,CAQnF;AACD,uDAAuD;AACvD,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,yBAAyB;AACzB,wBAAgB,eAAe,CAAC,IAAI,EAAE,UAAU,GAAG,OAAO,CAAC,MAAM,CAAC,CAEjE;AAED,0BAA0B;AAC1B,wBAAgB,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAS9C;AAED,+DAA+D;AAC/D,wBAAgB,WAAW,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAE/C;AAED,yBAAyB;AACzB,wBAAsB,SAAS,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAGhE;AAED,mDAAmD;AACnD,wBAAgB,SAAS,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAS/C"}
@@ -3,17 +3,43 @@ import { FNV1A_PRIME_32 } from "./constants/crypto.js";
3
3
  import { HASH_SEED_FNV1A } from "./constants/hash.js";
4
4
  /** Number of hex characters kept by shortHash (8 hex chars = 32 bits) */
5
5
  const SHORT_HASH_LENGTH = 8;
6
+ // Hashes participate in cache and request identities after project modules may
7
+ // have executed in the shared realm. Capture the small set of primordials used
8
+ // by that boundary before project code can replace their implementations.
9
+ const IntrinsicTextEncoder = TextEncoder;
10
+ const IntrinsicUint8Array = Uint8Array;
11
+ const NumberPrototypeToString = Number.prototype.toString;
12
+ const ObjectGetOwnPropertyDescriptor = Object.getOwnPropertyDescriptor;
13
+ const ObjectGetPrototypeOf = Object.getPrototypeOf;
14
+ const ReflectApply = Reflect.apply;
15
+ const StringPrototypePadStart = String.prototype.padStart;
16
+ const SubtleCryptoDigest = dntShim.crypto.subtle.digest;
17
+ const TextEncoderPrototypeEncode = TextEncoder.prototype.encode;
18
+ const cryptoSubtle = dntShim.crypto.subtle;
19
+ const hashTextEncoder = new IntrinsicTextEncoder();
20
+ const TypedArrayPrototype = ObjectGetPrototypeOf(IntrinsicUint8Array.prototype);
21
+ const TypedArrayLengthGetter = ObjectGetOwnPropertyDescriptor(TypedArrayPrototype, "length").get;
22
+ function typedArrayLength(value) {
23
+ return ReflectApply(TypedArrayLengthGetter, value, []);
24
+ }
6
25
  function toHex(buffer) {
7
- return Array.from(new Uint8Array(buffer), (b) => b.toString(16).padStart(2, "0")).join("");
26
+ const bytes = new IntrinsicUint8Array(buffer);
27
+ let result = "";
28
+ const length = typedArrayLength(bytes);
29
+ for (let index = 0; index < length; index++) {
30
+ const hex = ReflectApply(NumberPrototypeToString, bytes[index], [16]);
31
+ result += ReflectApply(StringPrototypePadStart, hex, [2, "0"]);
32
+ }
33
+ return result;
8
34
  }
9
35
  /** Compute the lowercase hex SHA-256 digest of a UTF-8 string. */
10
36
  export async function computeHash(content) {
11
- const data = new TextEncoder().encode(content);
12
- return toHex(await dntShim.crypto.subtle.digest("SHA-256", data));
37
+ const data = ReflectApply(TextEncoderPrototypeEncode, hashTextEncoder, [content]);
38
+ return toHex(await ReflectApply(SubtleCryptoDigest, cryptoSubtle, ["SHA-256", data]));
13
39
  }
14
40
  /** Compute the lowercase hex SHA-256 digest of raw bytes. */
15
41
  export async function computeHashBytes(bytes) {
16
- return toHex(await dntShim.crypto.subtle.digest("SHA-256", bytes));
42
+ return toHex(await ReflectApply(SubtleCryptoDigest, cryptoSubtle, ["SHA-256", bytes]));
17
43
  }
18
44
  /** Compute code hash. */
19
45
  export function computeCodeHash(code) {
@@ -40,8 +66,8 @@ export async function shortHash(content) {
40
66
  /** FNV-1a hash for strings - returns hex string */
41
67
  export function fnv1aHash(input) {
42
68
  let hash = HASH_SEED_FNV1A >>> 0;
43
- for (const char of input) {
44
- hash ^= char.charCodeAt(0);
69
+ for (let index = 0; index < input.length; index++) {
70
+ hash ^= input.charCodeAt(index);
45
71
  hash = Math.imul(hash, FNV1A_PRIME_32);
46
72
  }
47
73
  return (hash >>> 0).toString(16);
@@ -0,0 +1,16 @@
1
+ interface CryptoUuidSource {
2
+ randomUUID?: () => string;
3
+ getRandomValues?: (bytes: Uint8Array) => Uint8Array;
4
+ }
5
+ /** Generate a secure RFC 4122 version 4 UUID across browser Crypto implementations. */
6
+ export declare function generateUuid(cryptoImpl?: CryptoUuidSource | null | undefined): string;
7
+ /** Generate a unique ID with optional prefix (e.g., "msg-a1B2c3D4e5F6g7H8") */
8
+ export declare function generateId(prefix?: string): string;
9
+ /** Create an ID generator with fixed prefix and optional configuration */
10
+ export declare function createIdGenerator(options: {
11
+ prefix?: string;
12
+ separator?: string;
13
+ size?: number;
14
+ }): () => string;
15
+ export {};
16
+ //# sourceMappingURL=id.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"id.d.ts","sourceRoot":"","sources":["../../../src/src/utils/id.ts"],"names":[],"mappings":"AAyCA,UAAU,gBAAgB;IACxB,UAAU,CAAC,EAAE,MAAM,MAAM,CAAC;IAC1B,eAAe,CAAC,EAAE,CAAC,KAAK,EAAE,UAAU,KAAK,UAAU,CAAC;CACrD;AAED,uFAAuF;AACvF,wBAAgB,YAAY,CAC1B,UAAU,GAAE,gBAAgB,GAAG,IAAI,GAAG,SAEzB,GACZ,MAAM,CAmBR;AAED,+EAA+E;AAC/E,wBAAgB,UAAU,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,CAGlD;AAED,0EAA0E;AAC1E,wBAAgB,iBAAiB,CAAC,OAAO,EAAE;IACzC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,IAAI,CAAC,EAAE,MAAM,CAAC;CACf,GAAG,MAAM,MAAM,CAQf"}