cursedbelt-core 2.1.0 → 2.1.1

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 (152) hide show
  1. package/dist/core/activity/index.d.ts +2 -2
  2. package/dist/core/activity/index.js +1 -1
  3. package/dist/core/activity/model.d.ts +2 -2
  4. package/dist/core/analytics/index.d.ts +2 -2
  5. package/dist/core/analytics/index.js +2 -2
  6. package/dist/core/category/index.d.ts +3 -3
  7. package/dist/core/category/index.js +2 -2
  8. package/dist/core/category/memoryStore.d.ts +1 -1
  9. package/dist/core/category/memoryStore.js +1 -1
  10. package/dist/core/category/tree.d.ts +1 -1
  11. package/dist/core/colorScheme/index.d.ts +1 -1
  12. package/dist/core/colorScheme/index.js +1 -1
  13. package/dist/core/folder-tree/actions.d.ts +1 -1
  14. package/dist/core/folder-tree/actions.js +1 -1
  15. package/dist/core/folder-tree/index.d.ts +3 -3
  16. package/dist/core/folder-tree/index.js +3 -3
  17. package/dist/core/folder-tree/tree.js +1 -1
  18. package/dist/core/master-lock/index.d.ts +4 -4
  19. package/dist/core/master-lock/index.js +4 -4
  20. package/dist/core/master-lock/wire.d.ts +1 -1
  21. package/dist/core/media/ffmpeg.d.ts +1 -1
  22. package/dist/core/media/format.d.ts +1 -1
  23. package/dist/core/media/index.d.ts +12 -12
  24. package/dist/core/media/index.js +11 -11
  25. package/dist/core/media/mediaItem.d.ts +1 -1
  26. package/dist/core/media/renderPlan.d.ts +1 -1
  27. package/dist/core/media/renderPlan.js +1 -1
  28. package/dist/core/media/validate.d.ts +1 -1
  29. package/dist/core/media/validate.js +1 -1
  30. package/dist/core/navigation/coverageTest.d.ts +1 -1
  31. package/dist/core/navigation/coverageTest.js +1 -1
  32. package/dist/core/navigation/index.d.ts +6 -6
  33. package/dist/core/navigation/index.js +6 -6
  34. package/dist/core/navigation/migrateNavPreferences.d.ts +1 -1
  35. package/dist/core/navigation/navigationSelectors.d.ts +1 -1
  36. package/dist/core/navigation/navigationSelectors.js +1 -1
  37. package/dist/core/navigation/searchCatalogue.d.ts +1 -1
  38. package/dist/core/palette/fuzzyRank.d.ts +1 -1
  39. package/dist/core/palette/index.d.ts +3 -3
  40. package/dist/core/palette/index.js +3 -3
  41. package/dist/core/sharing/index.d.ts +2 -2
  42. package/dist/core/sharing/index.js +1 -1
  43. package/dist/core/tokens/registry.d.ts +2 -2
  44. package/dist/core/tokens/registry.js +1 -1
  45. package/dist/core/uiScale/index.d.ts +2 -2
  46. package/dist/core/uiScale/index.js +2 -2
  47. package/dist/core/uiScale/uiScaleStore.js +1 -1
  48. package/dist/core/wire/__fixtures__/rowsMarshalWorker.js +1 -1
  49. package/dist/core/wire/index.d.ts +4 -4
  50. package/dist/core/wire/index.js +4 -4
  51. package/dist/core/wire/ingress.d.ts +1 -1
  52. package/dist/core/wire/ingress.js +3 -3
  53. package/dist/core/wire/marshalWorker.d.ts +1 -1
  54. package/dist/core/wire/marshalWorker.js +2 -2
  55. package/dist/core/wire/marshalling.js +1 -1
  56. package/dist/ctgr/chunkAccumulator.d.ts +1 -1
  57. package/dist/ctgr/chunkAccumulator.js +2 -2
  58. package/dist/ctgr/chunkStore.d.ts +1 -1
  59. package/dist/ctgr/chunkStore.js +2 -2
  60. package/dist/ctgr/codec.d.ts +1 -1
  61. package/dist/ctgr/codec.js +5 -5
  62. package/dist/ctgr/index.d.ts +9 -9
  63. package/dist/ctgr/index.js +9 -9
  64. package/dist/ctgr/v0compat.d.ts +1 -1
  65. package/dist/ctgr/v0compat.js +2 -2
  66. package/dist/index.d.ts +2 -2
  67. package/dist/index.js +2 -2
  68. package/dist/testing/index.d.ts +3 -3
  69. package/dist/testing/index.js +3 -3
  70. package/package.json +2 -2
  71. package/src/config/appConfig.spec.ts +1 -1
  72. package/src/core/activity/index.ts +2 -2
  73. package/src/core/activity/model.ts +2 -2
  74. package/src/core/analytics/index.ts +2 -2
  75. package/src/core/analytics/range.spec.ts +1 -1
  76. package/src/core/analytics/schedule.spec.ts +1 -1
  77. package/src/core/category/category.spec.ts +1 -1
  78. package/src/core/category/index.ts +3 -3
  79. package/src/core/category/memoryStore.ts +2 -2
  80. package/src/core/category/tree.ts +1 -1
  81. package/src/core/color.spec.ts +1 -1
  82. package/src/core/colorScheme/colorScheme.spec.ts +1 -1
  83. package/src/core/colorScheme/index.ts +1 -1
  84. package/src/core/download.spec.ts +1 -1
  85. package/src/core/duplicates/index.spec.ts +1 -1
  86. package/src/core/events/ccEventBus.spec.ts +1 -1
  87. package/src/core/file-tree/fileTreeModel.spec.ts +1 -1
  88. package/src/core/folder-tree/actions.spec.ts +2 -2
  89. package/src/core/folder-tree/actions.ts +2 -2
  90. package/src/core/folder-tree/index.ts +3 -3
  91. package/src/core/folder-tree/path.spec.ts +1 -1
  92. package/src/core/folder-tree/tree.spec.ts +1 -1
  93. package/src/core/folder-tree/tree.ts +1 -1
  94. package/src/core/master-lock/index.ts +4 -4
  95. package/src/core/master-lock/kdf.spec.ts +2 -2
  96. package/src/core/master-lock/presence.spec.ts +1 -1
  97. package/src/core/master-lock/wire.spec.ts +1 -1
  98. package/src/core/master-lock/wire.ts +1 -1
  99. package/src/core/media/bgRemoval.spec.ts +1 -1
  100. package/src/core/media/ffmpeg.spec.ts +2 -2
  101. package/src/core/media/ffmpeg.ts +1 -1
  102. package/src/core/media/format.spec.ts +1 -1
  103. package/src/core/media/format.ts +1 -1
  104. package/src/core/media/index.ts +12 -12
  105. package/src/core/media/mediaItem.spec.ts +2 -2
  106. package/src/core/media/mediaItem.ts +1 -1
  107. package/src/core/media/renderPlan.spec.ts +1 -1
  108. package/src/core/media/renderPlan.ts +2 -2
  109. package/src/core/media/segment.spec.ts +1 -1
  110. package/src/core/media/size.spec.ts +1 -1
  111. package/src/core/media/trim.spec.ts +1 -1
  112. package/src/core/media/validate.spec.ts +2 -2
  113. package/src/core/media/validate.ts +2 -2
  114. package/src/core/media/videoCuts.spec.ts +1 -1
  115. package/src/core/navigation/coverageTest.ts +2 -2
  116. package/src/core/navigation/index.ts +6 -6
  117. package/src/core/navigation/migrateNavPreferences.ts +1 -1
  118. package/src/core/navigation/navigation.spec.ts +1 -1
  119. package/src/core/navigation/navigationSelectors.ts +1 -1
  120. package/src/core/navigation/searchCatalogue.ts +1 -1
  121. package/src/core/net/reconnectSchedule.spec.ts +1 -1
  122. package/src/core/palette/fuzzyRank.ts +1 -1
  123. package/src/core/palette/index.ts +3 -3
  124. package/src/core/palette/palette.spec.ts +4 -4
  125. package/src/core/schema/projection.spec.ts +1 -1
  126. package/src/core/sharing/index.ts +2 -2
  127. package/src/core/sharing/model.spec.ts +1 -1
  128. package/src/core/tokens/registry.spec.ts +1 -1
  129. package/src/core/tokens/registry.ts +2 -2
  130. package/src/core/uiScale/index.ts +2 -2
  131. package/src/core/uiScale/uiScale.spec.ts +1 -1
  132. package/src/core/uiScale/uiScaleStore.ts +1 -1
  133. package/src/core/wire/__fixtures__/rowsMarshalWorker.ts +1 -1
  134. package/src/core/wire/index.ts +4 -4
  135. package/src/core/wire/ingress.spec.ts +2 -2
  136. package/src/core/wire/ingress.ts +3 -3
  137. package/src/core/wire/marshalWorker.spec.ts +2 -2
  138. package/src/core/wire/marshalWorker.ts +2 -2
  139. package/src/core/wire/marshalling.spec.ts +1 -1
  140. package/src/core/wire/marshalling.ts +1 -1
  141. package/src/core/wire/wireHub.spec.ts +1 -1
  142. package/src/ctgr/chunkAccumulator.ts +3 -3
  143. package/src/ctgr/chunkStore.spec.ts +2 -2
  144. package/src/ctgr/chunkStore.ts +3 -3
  145. package/src/ctgr/codec.spec.ts +4 -4
  146. package/src/ctgr/codec.ts +5 -5
  147. package/src/ctgr/index.ts +9 -9
  148. package/src/ctgr/v0compat.spec.ts +2 -2
  149. package/src/ctgr/v0compat.ts +3 -3
  150. package/src/index.ts +2 -2
  151. package/src/testTmpRoot.spec.ts +1 -1
  152. package/src/testing/index.ts +3 -3
@@ -1,4 +1,4 @@
1
- import { AppError } from '../../shared/errors';
1
+ import { AppError } from '../../shared/errors.js';
2
2
  /** Above this, `validate` + `transform` are offloaded to a Worker (02 §7.1). */
3
3
  export const MARSHALLER_WORKER_OFFLOAD_BYTES = 512 * 1024;
4
4
  /**
@@ -61,7 +61,7 @@
61
61
  * - Inconsistency errors (e.g., second chunk claims different total count) delete the entry immediately; recovery requires retransmitting all chunks from the client
62
62
  * - The service itself is a singleton; do NOT create multiple instances per server or request thread
63
63
  */
64
- import type { CtgrDecoded } from './types';
64
+ import type { CtgrDecoded } from './types.js';
65
65
  /**
66
66
  * Configuration for ChunkAccumulator resource limits and timing behavior.
67
67
  *
@@ -61,8 +61,8 @@
61
61
  * - Inconsistency errors (e.g., second chunk claims different total count) delete the entry immediately; recovery requires retransmitting all chunks from the client
62
62
  * - The service itself is a singleton; do NOT create multiple instances per server or request thread
63
63
  */
64
- import { decodePayload, parseChunk } from './codec';
65
- import { sha256Hex } from './digest';
64
+ import { decodePayload, parseChunk } from './codec.js';
65
+ import { sha256Hex } from './digest.js';
66
66
  /**
67
67
  * ChunkAccumulator — The hardened service for multi-chunk payload assembly.
68
68
  *
@@ -1,4 +1,4 @@
1
- import type { CtgrDecoded } from './types';
1
+ import type { CtgrDecoded } from './types.js';
2
2
  export interface ChunkStoreOpts {
3
3
  /** Max concurrent in-flight (incomplete) payloads. Default 200. */
4
4
  maxInFlight?: number;
@@ -9,8 +9,8 @@
9
9
  * It NEVER throws: a malformed/corrupt/oversized payload returns an `Error` the
10
10
  * middleware maps to a 400; an intermediate chunk returns `false` (→ 202).
11
11
  */
12
- import { decodePayload, parseChunk } from './codec';
13
- import { sha256Hex } from './digest';
12
+ import { decodePayload, parseChunk } from './codec.js';
13
+ import { sha256Hex } from './digest.js';
14
14
  export class ChunkStore {
15
15
  entries = new Map();
16
16
  maxInFlight;
@@ -1,4 +1,4 @@
1
- import { type CtgrDecoded, type CtgrMethod, type EncodedRequest, type EncodeOpts, type UploadedFile } from './types';
1
+ import { type CtgrDecoded, type CtgrMethod, type EncodedRequest, type EncodeOpts, type UploadedFile } from './types.js';
2
2
  /**
3
3
  * Encode a mutating request into one or more `/ctgr<XX>` GET-twin chunks. Small
4
4
  * bodies become a single chunk; large bodies gzip (when over the threshold) and split
@@ -11,11 +11,11 @@
11
11
  * double-base64'd and whose swap/reverse was trivially-reversible obfuscation, not
12
12
  * protection — the real protection (getOnly JWT claim + CSRF guard) is unchanged.
13
13
  */
14
- import { fromBase64, fromBase64url, toBase64url } from './base64url';
15
- import { gunzip, gzip } from './compress';
16
- import { crc32 } from './crc32';
17
- import { sha256Hex } from './digest';
18
- import { ABBREV_TO_METHOD, CTGR_WIRE_VERSION, METHOD_TO_ABBREV, } from './types';
14
+ import { fromBase64, fromBase64url, toBase64url } from './base64url.js';
15
+ import { gunzip, gzip } from './compress.js';
16
+ import { crc32 } from './crc32.js';
17
+ import { sha256Hex } from './digest.js';
18
+ import { ABBREV_TO_METHOD, CTGR_WIRE_VERSION, METHOD_TO_ABBREV, } from './types.js';
19
19
  const DEFAULT_CHUNK_SIZE = 1800;
20
20
  const DEFAULT_GZIP_THRESHOLD = 1024;
21
21
  const textEncoder = new TextEncoder();
@@ -1,9 +1,9 @@
1
- export { fromBase64, fromBase64url, toBase64, toBase64url } from './base64url';
2
- export { ChunkAccumulator, type ChunkAccumulatorConfig, } from './chunkAccumulator';
3
- export { ChunkStore, type ChunkStoreOpts } from './chunkStore';
4
- export { decodePayload, decodeRequest, encodeRequest, extractFiles, type ParsedChunk, parseChunk, } from './codec';
5
- export { gunzip, gzip } from './compress';
6
- export { crc32 } from './crc32';
7
- export { sha256Hex } from './digest';
8
- export { ABBREV_TO_METHOD, CTGR_WIRE_VERSION, type CtgrAbbrev, type CtgrDecoded, type CtgrMethod, type EncodedChunk, type EncodedRequest, type EncodeOpts, METHOD_TO_ABBREV, type SerializedFile, type UploadedFile, } from './types';
9
- export { decodeV0Payload, V0ChunkStore, type V0ChunkStoreOpts } from './v0compat';
1
+ export { fromBase64, fromBase64url, toBase64, toBase64url } from './base64url.js';
2
+ export { ChunkAccumulator, type ChunkAccumulatorConfig, } from './chunkAccumulator.js';
3
+ export { ChunkStore, type ChunkStoreOpts } from './chunkStore.js';
4
+ export { decodePayload, decodeRequest, encodeRequest, extractFiles, type ParsedChunk, parseChunk, } from './codec.js';
5
+ export { gunzip, gzip } from './compress.js';
6
+ export { crc32 } from './crc32.js';
7
+ export { sha256Hex } from './digest.js';
8
+ export { ABBREV_TO_METHOD, CTGR_WIRE_VERSION, type CtgrAbbrev, type CtgrDecoded, type CtgrMethod, type EncodedChunk, type EncodedRequest, type EncodeOpts, METHOD_TO_ABBREV, type SerializedFile, type UploadedFile, } from './types.js';
9
+ export { decodeV0Payload, V0ChunkStore, type V0ChunkStoreOpts } from './v0compat.js';
@@ -6,12 +6,12 @@
6
6
  * The ChunkAccumulator is the primary abstraction for multi-chunk payload assembly;
7
7
  * ChunkStore is kept for backward compatibility (they are identical implementations).
8
8
  */
9
- export { fromBase64, fromBase64url, toBase64, toBase64url } from './base64url';
10
- export { ChunkAccumulator, } from './chunkAccumulator';
11
- export { ChunkStore } from './chunkStore';
12
- export { decodePayload, decodeRequest, encodeRequest, extractFiles, parseChunk, } from './codec';
13
- export { gunzip, gzip } from './compress';
14
- export { crc32 } from './crc32';
15
- export { sha256Hex } from './digest';
16
- export { ABBREV_TO_METHOD, CTGR_WIRE_VERSION, METHOD_TO_ABBREV, } from './types';
17
- export { decodeV0Payload, V0ChunkStore } from './v0compat';
9
+ export { fromBase64, fromBase64url, toBase64, toBase64url } from './base64url.js';
10
+ export { ChunkAccumulator, } from './chunkAccumulator.js';
11
+ export { ChunkStore } from './chunkStore.js';
12
+ export { decodePayload, decodeRequest, encodeRequest, extractFiles, parseChunk, } from './codec.js';
13
+ export { gunzip, gzip } from './compress.js';
14
+ export { crc32 } from './crc32.js';
15
+ export { sha256Hex } from './digest.js';
16
+ export { ABBREV_TO_METHOD, CTGR_WIRE_VERSION, METHOD_TO_ABBREV, } from './types.js';
17
+ export { decodeV0Payload, V0ChunkStore } from './v0compat.js';
@@ -1,4 +1,4 @@
1
- import type { CtgrDecoded, CtgrMethod } from './types';
1
+ import type { CtgrDecoded, CtgrMethod } from './types.js';
2
2
  /** Reverse the v0 client pipeline (`encode→reverse→swap→encode→swap`) and parse JSON. */
3
3
  export declare function decodeV0Payload(encoded: string): unknown;
4
4
  export interface V0ChunkStoreOpts {
@@ -9,8 +9,8 @@
9
9
  * heuristic, since v1 always sets `_cv=1`. v0 carried the method only in the path
10
10
  * (`/ctgr<XX>`), so the middleware passes the path-derived method in.
11
11
  */
12
- import { fromBase64 } from './base64url';
13
- import { extractFiles } from './codec';
12
+ import { fromBase64 } from './base64url.js';
13
+ import { extractFiles } from './codec.js';
14
14
  const decodeBase64Utf8 = (str) => new TextDecoder().decode(fromBase64(str));
15
15
  const reverseString = (str) => str.split('').reverse().join('');
16
16
  const swapEnds = (str) => {
package/dist/index.d.ts CHANGED
@@ -11,5 +11,5 @@
11
11
  * drag 47 dependencies into every consumer.
12
12
  */
13
13
  export declare const VERSION = "1.0.0";
14
- export { contrastText } from './core/color';
15
- export { isSiteCopyKey, SITE_COPY_BAKED_ONLY, SITE_COPY_DEFAULTS, SITE_COPY_KEYS, SITE_COPY_MAX_VALUE_LENGTH, type SiteCopyKey, } from './core/site/siteCopy';
14
+ export { contrastText } from './core/color.js';
15
+ export { isSiteCopyKey, SITE_COPY_BAKED_ONLY, SITE_COPY_DEFAULTS, SITE_COPY_KEYS, SITE_COPY_MAX_VALUE_LENGTH, type SiteCopyKey, } from './core/site/siteCopy.js';
package/dist/index.js CHANGED
@@ -13,5 +13,5 @@
13
13
  export const VERSION = '1.0.0';
14
14
  // The two root-level conveniences the pre-split "." barrel actually served:
15
15
  // the WCAG readable-foreground picker and the baked marketing-copy contract.
16
- export { contrastText } from './core/color';
17
- export { isSiteCopyKey, SITE_COPY_BAKED_ONLY, SITE_COPY_DEFAULTS, SITE_COPY_KEYS, SITE_COPY_MAX_VALUE_LENGTH, } from './core/site/siteCopy';
16
+ export { contrastText } from './core/color.js';
17
+ export { isSiteCopyKey, SITE_COPY_BAKED_ONLY, SITE_COPY_DEFAULTS, SITE_COPY_KEYS, SITE_COPY_MAX_VALUE_LENGTH, } from './core/site/siteCopy.js';
@@ -1,3 +1,3 @@
1
- export { installCheapDomInspect } from "./domInspect";
2
- export { asBody, bytesResponse, bytesStream } from "./bytes";
3
- export { type FetchImpl, fakeFetch } from "./fakeFetch";
1
+ export { installCheapDomInspect } from "./domInspect.js";
2
+ export { asBody, bytesResponse, bytesStream } from "./bytes.js";
3
+ export { type FetchImpl, fakeFetch } from "./fakeFetch.js";
@@ -6,6 +6,6 @@
6
6
  // can `import { installCheapDomInspect } from "cursedbelt-core/testing"` instead of
7
7
  // keeping a ~60-line hand-port of domInspect.ts — the file already lived here,
8
8
  // it just had no export.
9
- export { installCheapDomInspect } from "./domInspect";
10
- export { asBody, bytesResponse, bytesStream } from "./bytes";
11
- export { fakeFetch } from "./fakeFetch";
9
+ export { installCheapDomInspect } from "./domInspect.js";
10
+ export { asBody, bytesResponse, bytesStream } from "./bytes.js";
11
+ export { fakeFetch } from "./fakeFetch.js";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cursedbelt-core",
3
- "version": "2.1.0",
3
+ "version": "2.1.1",
4
4
  "license": "ISC",
5
5
  "type": "module",
6
6
  "description": "Framework-agnostic core of the cursedbelt split — isomorphic domain logic. cwip below it, cursedbelt-server and cursedbelt (react) above it.",
@@ -362,7 +362,7 @@
362
362
  },
363
363
  "dependencies": {
364
364
  "@leeoniya/ufuzzy": "^1.0.19",
365
- "cwip": "^4.1.0"
365
+ "cwip": "^4.6.0"
366
366
  },
367
367
  "peerDependencies": {
368
368
  "zod": "^4.4.0"
@@ -1,5 +1,5 @@
1
1
  import { describe, expect, it } from 'bun:test';
2
- import { AppConfigSchema, effectiveSignupMode, featureKeysOf, resolveInstanceFeatures, ROUTE_PATH_RE } from './appConfig';
2
+ import { AppConfigSchema, effectiveSignupMode, featureKeysOf, resolveInstanceFeatures, ROUTE_PATH_RE } from './appConfig.js';
3
3
 
4
4
  const base = (over: Record<string, unknown> = {}) => ({
5
5
  configVersion: 1,
@@ -12,10 +12,10 @@ export {
12
12
  describeActivityResource,
13
13
  isActivityAction,
14
14
  isActivityOutcome,
15
- } from "./model";
15
+ } from "./model.js";
16
16
  export type {
17
17
  ActivityEvent,
18
18
  ActivityEventInput,
19
19
  ActivityOutcome,
20
20
  ActivityResource,
21
- } from "./model";
21
+ } from "./model.js";
@@ -30,7 +30,7 @@
30
30
  * - **`id` is source-qualified** (`log:41`, `share:12`), because the stream is a
31
31
  * UNION over more than one table and two tables' autoincrements collide at 1.
32
32
  */
33
- import type { ShareEvent } from "../sharing/model";
33
+ import type { ShareEvent } from "../sharing/model.js";
34
34
 
35
35
  /** How it went. `denied` is its own outcome rather than an `error`: a refused
36
36
  * action is the single most interesting row in an audit trail, and one that
@@ -44,7 +44,7 @@ export const isActivityOutcome = (value: unknown): value is ActivityOutcome =>
44
44
 
45
45
  /**
46
46
  * What was acted on: `(app, kind, id)` — deliberately identical to
47
- * {@link import("../sharing/model").ShareResource}, so a resource can be handed
47
+ * {@link import("../sharing/model.js").ShareResource}, so a resource can be handed
48
48
  * from one primitive to the other without a translation layer.
49
49
  */
50
50
  export interface ActivityResource {
@@ -14,5 +14,5 @@
14
14
  *
15
15
  * The React furniture that renders it lives in `cursedbelt/react/analytics`.
16
16
  */
17
- export * from './range';
18
- export * from './schedule';
17
+ export * from './range.js';
18
+ export * from './schedule.js';
@@ -16,7 +16,7 @@ import {
16
16
  startOfDay,
17
17
  startOfHour,
18
18
  unitForSpan,
19
- } from './range';
19
+ } from './range.js';
20
20
 
21
21
  /** 2026-08-13 14:30 LOCAL — the tests are about local calendar behaviour. */
22
22
  const NOW = new Date(2026, 7, 13, 14, 30, 0).getTime();
@@ -10,7 +10,7 @@ import {
10
10
  simulateSchedule,
11
11
  stretchAt,
12
12
  sweepFleetSizes,
13
- } from './schedule';
13
+ } from './schedule.js';
14
14
 
15
15
  const MIN = 60_000;
16
16
  const item = (id: string, minutes: number, rest: Partial<ScheduleItem> = {}): ScheduleItem => ({
@@ -7,7 +7,7 @@ import {
7
7
  flattenCategoryForest,
8
8
  wouldCreateCycle,
9
9
  type Category,
10
- } from './index';
10
+ } from './index.js';
11
11
 
12
12
  const cat = (id: string, parentId: string | null, label: string, order = 0): Category => ({
13
13
  id,
@@ -8,12 +8,12 @@ export type {
8
8
  CategoryCreateInput,
9
9
  CategoryNode,
10
10
  CategoryStore,
11
- } from './types';
11
+ } from './types.js';
12
12
  export {
13
13
  buildCategoryForest,
14
14
  categoryPath,
15
15
  descendantCategoryIds,
16
16
  flattenCategoryForest,
17
17
  wouldCreateCycle,
18
- } from './tree';
19
- export { createMemoryCategoryStore } from './memoryStore';
18
+ } from './tree.js';
19
+ export { createMemoryCategoryStore } from './memoryStore.js';
@@ -1,5 +1,5 @@
1
- import type { Category, CategoryCreateInput, CategoryStore } from './types';
2
- import { wouldCreateCycle } from './tree';
1
+ import type { Category, CategoryCreateInput, CategoryStore } from './types.js';
2
+ import { wouldCreateCycle } from './tree.js';
3
3
 
4
4
  /**
5
5
  * Zero-config in-memory {@link CategoryStore}: a per-boot `Map` per tenant, so a
@@ -1,4 +1,4 @@
1
- import type { Category, CategoryNode } from './types';
1
+ import type { Category, CategoryNode } from './types.js';
2
2
 
3
3
  /** Sort siblings by explicit `order`, then label (locale-aware, stable). */
4
4
  function compareSiblings(a: Category, b: Category): number {
@@ -1,5 +1,5 @@
1
1
  import { describe, expect, it } from 'bun:test';
2
- import { contrastText } from './color';
2
+ import { contrastText } from './color.js';
3
3
 
4
4
  describe('contrastText', () => {
5
5
  it('returns white on dark backgrounds', () => {
@@ -4,7 +4,7 @@ import {
4
4
  type ColorSchemeStorage,
5
5
  createColorSchemeStore,
6
6
  type ResolvedColorScheme,
7
- } from './index';
7
+ } from './index.js';
8
8
 
9
9
  const makeStorage = (): ColorSchemeStorage & { map: Map<string, string> } => {
10
10
  const map = new Map<string, string>();
@@ -20,4 +20,4 @@ export {
20
20
  setColorSchemeMode,
21
21
  subscribeColorScheme,
22
22
  toggleColorScheme,
23
- } from './colorSchemeStore';
23
+ } from './colorSchemeStore.js';
@@ -1,5 +1,5 @@
1
1
  import { describe, expect, test } from 'bun:test';
2
- import { base64ToBytes, downloadBlob } from './download';
2
+ import { base64ToBytes, downloadBlob } from './download.js';
3
3
 
4
4
  describe('base64ToBytes', () => {
5
5
  test('decodes base64 to the original bytes', () => {
@@ -13,7 +13,7 @@ import {
13
13
  normalizeName,
14
14
  SIZE_TOLERANCE,
15
15
  sizesClose,
16
- } from "./index";
16
+ } from "./index.js";
17
17
 
18
18
  describe("normalizeName", () => {
19
19
  it("reduces the marks a copy picks up to the same stem", () => {
@@ -1,5 +1,5 @@
1
1
  import { describe, expect, it } from 'bun:test';
2
- import { createCcEventBus, MAX_EVENT_DEPTH } from './ccEventBus';
2
+ import { createCcEventBus, MAX_EVENT_DEPTH } from './ccEventBus.js';
3
3
 
4
4
  describe('CCEventBus', () => {
5
5
  it('delivers to every subscriber of a type and to nobody else', async () => {
@@ -13,7 +13,7 @@ import {
13
13
  resolveDrop,
14
14
  resolveKeyboardMove,
15
15
  describeDrop,
16
- } from './fileTreeModel';
16
+ } from './fileTreeModel.js';
17
17
 
18
18
  /**
19
19
  * The shape collections actually feeds this: albums at the top level, each one a folder,
@@ -9,8 +9,8 @@
9
9
  * both are pinned here side by side rather than each in isolation.
10
10
  */
11
11
  import { describe, expect, test } from "bun:test";
12
- import { folderMoveTargets, planFolderMergeInto } from "./actions";
13
- import { buildFolderTree, planFolderMove } from "./tree";
12
+ import { folderMoveTargets, planFolderMergeInto } from "./actions.js";
13
+ import { buildFolderTree, planFolderMove } from "./tree.js";
14
14
 
15
15
  const PATHS = [
16
16
  "rock",
@@ -34,8 +34,8 @@ import {
34
34
  isFolderPathUnder,
35
35
  parseFolderPath,
36
36
  serializeFolderPath,
37
- } from "./path";
38
- import type { FolderNode, FolderRemap } from "./tree";
37
+ } from "./path.js";
38
+ import type { FolderNode, FolderRemap } from "./tree.js";
39
39
 
40
40
  /**
41
41
  * Move everything at or under `source` INTO `destination`, and stop `source` existing.
@@ -26,7 +26,7 @@ export {
26
26
  normalizeFolderName,
27
27
  parseFolderPath,
28
28
  serializeFolderPath,
29
- } from "./path";
29
+ } from "./path.js";
30
30
  export {
31
31
  buildFolderIndex,
32
32
  buildFolderTree,
@@ -37,10 +37,10 @@ export {
37
37
  planFolderDelete,
38
38
  planFolderMove,
39
39
  planFolderRename,
40
- } from "./tree";
40
+ } from "./tree.js";
41
41
  export {
42
42
  type FolderDeleteMode,
43
43
  type FolderTarget,
44
44
  folderMoveTargets,
45
45
  planFolderMergeInto,
46
- } from "./actions";
46
+ } from "./actions.js";
@@ -7,7 +7,7 @@ import {
7
7
  isValidFolderName,
8
8
  parseFolderPath,
9
9
  serializeFolderPath,
10
- } from "./path";
10
+ } from "./path.js";
11
11
 
12
12
  describe("folder path serialization", () => {
13
13
  test("round-trips a simple nested path", () => {
@@ -7,7 +7,7 @@ import {
7
7
  planFolderDelete,
8
8
  planFolderMove,
9
9
  planFolderRename,
10
- } from "./tree";
10
+ } from "./tree.js";
11
11
 
12
12
  /** A compact "name(child,child)" view of a subtree, for readable assertions. */
13
13
  function shape(nodes: readonly FolderNode[]): string {
@@ -17,7 +17,7 @@ import {
17
17
  normalizeFolderName,
18
18
  parseFolderPath,
19
19
  serializeFolderPath,
20
- } from "./path";
20
+ } from "./path.js";
21
21
 
22
22
  /** A node in the derived tree. `path` is the full segment array from the root; a
23
23
  * `child` node's path is its parent's plus one segment. */
@@ -16,7 +16,7 @@ export {
16
16
  isMasterLockKdfParams,
17
17
  newMasterLockKdfParams,
18
18
  unb64u,
19
- } from "./kdf";
19
+ } from "./kdf.js";
20
20
  export {
21
21
  BASE_DELAY_MS,
22
22
  DEFAULT_IDLE_MS,
@@ -27,7 +27,7 @@ export {
27
27
  clampIdleMs,
28
28
  delayAfter,
29
29
  windowRemaining,
30
- } from "./policy";
30
+ } from "./policy.js";
31
31
  export {
32
32
  MASTER_LOCK_COOKIE,
33
33
  masterLockCookieName,
@@ -46,10 +46,10 @@ export {
46
46
  type MasterLockSettingsRequest,
47
47
  type MasterLockStatus,
48
48
  type MasterLockUnlockRequest,
49
- } from "./wire";
49
+ } from "./wire.js";
50
50
  export {
51
51
  PRESENCE_ATTRIBUTE,
52
52
  type PresenceMedia,
53
53
  isPresenceMedia,
54
54
  isSomebodyWatching,
55
- } from "./presence";
55
+ } from "./presence.js";
@@ -17,8 +17,8 @@ import {
17
17
  deriveMasterLockVerifier,
18
18
  isMasterLockKdfParams,
19
19
  newMasterLockKdfParams,
20
- } from ".";
21
- import { b64u, unb64u } from "./kdf";
20
+ } from "./index.js";
21
+ import { b64u, unb64u } from "./kdf.js";
22
22
 
23
23
  // The exact fixture `apps/vault/src/crypto/kdf.test.ts` derives against.
24
24
  const FIXED: MasterLockKdfParams = {
@@ -10,7 +10,7 @@
10
10
  * hole it was asked to close.
11
11
  */
12
12
  import { describe, expect, test } from "bun:test";
13
- import { PRESENCE_ATTRIBUTE, type PresenceMedia, isPresenceMedia, isSomebodyWatching } from "./presence";
13
+ import { PRESENCE_ATTRIBUTE, type PresenceMedia, isPresenceMedia, isSomebodyWatching } from "./presence.js";
14
14
 
15
15
  const media = (over: Partial<PresenceMedia> & { presence?: string } = {}): PresenceMedia => ({
16
16
  paused: false,
@@ -9,7 +9,7 @@
9
9
  * it was told to mount and the browser would fetch what it was told to fetch.
10
10
  */
11
11
  import { describe, expect, it } from "bun:test";
12
- import { MASTER_LOCK_PATHS, MASTER_LOCK_PREFIX } from "./wire";
12
+ import { MASTER_LOCK_PATHS, MASTER_LOCK_PREFIX } from "./wire.js";
13
13
 
14
14
  describe("MASTER_LOCK_PATHS", () => {
15
15
  it("keeps every surface under the one prefix the guard reserves", () => {
@@ -4,7 +4,7 @@
4
4
  * One module both halves import, so a rename cannot make the browser talk to a route that
5
5
  * no longer exists.
6
6
  */
7
- import type { MasterLockKdfParams } from "./kdf";
7
+ import type { MasterLockKdfParams } from "./kdf.js";
8
8
 
9
9
  /**
10
10
  * The mount prefix. Everything under it is reachable while LOCKED (it is how you unlock);
@@ -1,5 +1,5 @@
1
1
  import { describe, expect, test } from 'bun:test';
2
- import { floodFillBGS } from './bgRemoval';
2
+ import { floodFillBGS } from './bgRemoval.js';
3
3
 
4
4
  /** Build a `w×h` RGB buffer from a `pick(x,y) → [r,g,b]` function. */
5
5
  function rgb(
@@ -7,8 +7,8 @@ import {
7
7
  parseFfmpegProgress,
8
8
  parseFfprobe,
9
9
  videoCodecPlan,
10
- } from './ffmpeg';
11
- import type { VideoTrimSpec } from './types';
10
+ } from './ffmpeg.js';
11
+ import type { VideoTrimSpec } from './types.js';
12
12
 
13
13
  const trim = (over: Partial<VideoTrimSpec> = {}): VideoTrimSpec => ({
14
14
  inputPath: '/in.mp4',
@@ -3,7 +3,7 @@
3
3
  // (`server/media-bun/video.ts` spawns these against native ffmpeg) and the browser editor
4
4
  // (`react/media` executes the same argv against ffmpeg.wasm). Unit tested without ffmpeg.
5
5
 
6
- import type { VideoFormat, VideoProgressEvent, VideoQuality, VideoTrimSpec } from './types';
6
+ import type { VideoFormat, VideoProgressEvent, VideoQuality, VideoTrimSpec } from './types.js';
7
7
 
8
8
  /** Codec + rate-control plan for an output container at a quality preset. */
9
9
  export interface VideoCodecPlan {
@@ -5,7 +5,7 @@ import {
5
5
  imageFormatToMime,
6
6
  mimeToImageFormat,
7
7
  pickThumbnailFormat,
8
- } from './format';
8
+ } from './format.js';
9
9
 
10
10
  describe('format helpers', () => {
11
11
  test('mime + extension lookup', () => {
@@ -1,7 +1,7 @@
1
1
  // Pure format helpers — MIME/extension lookup, quality clamping, thumbnail-format
2
2
  // selection. No npm deps; shared by the server adapter, the React layer, and tests.
3
3
 
4
- import type { ImageOutputFormat } from './types';
4
+ import type { ImageOutputFormat } from './types.js';
5
5
 
6
6
  export const IMAGE_OUTPUT_FORMATS: readonly ImageOutputFormat[] = ['jpeg', 'png', 'webp', 'avif'];
7
7