@agent-native/core 0.114.2 → 0.114.3

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 (75) hide show
  1. package/corpus/README.md +2 -2
  2. package/corpus/core/CHANGELOG.md +24 -0
  3. package/corpus/core/package.json +2 -1
  4. package/corpus/core/src/db/request-telemetry.ts +32 -8
  5. package/corpus/core/src/settings/store.ts +15 -6
  6. package/corpus/core/src/shared/optional-node-builtins.ts +66 -0
  7. package/corpus/core/src/templates/default/.agents/skills/feature-flags/SKILL.md +1 -1
  8. package/corpus/core/src/templates/headless/.agents/skills/feature-flags/SKILL.md +1 -1
  9. package/corpus/core/src/templates/workspace-core/.agents/skills/feature-flags/SKILL.md +1 -1
  10. package/corpus/core/src/vite/client.ts +5 -0
  11. package/corpus/templates/analytics/.agents/skills/feature-flags/SKILL.md +1 -1
  12. package/corpus/templates/assets/.agents/skills/feature-flags/SKILL.md +1 -1
  13. package/corpus/templates/assets/app/routes/brand-kits.$id.tsx +2 -2
  14. package/corpus/templates/brain/.agents/skills/feature-flags/SKILL.md +1 -1
  15. package/corpus/templates/calendar/.agents/skills/feature-flags/SKILL.md +1 -1
  16. package/corpus/templates/chat/.agents/skills/feature-flags/SKILL.md +1 -1
  17. package/corpus/templates/clips/.agents/skills/feature-flags/SKILL.md +1 -1
  18. package/corpus/templates/clips/shared/feature-flags.ts +1 -1
  19. package/corpus/templates/content/.agents/skills/feature-flags/SKILL.md +1 -1
  20. package/corpus/templates/design/.agents/skills/feature-flags/SKILL.md +1 -1
  21. package/corpus/templates/design/actions/update-file.ts +10 -1
  22. package/corpus/templates/design/app/components/design/DesignCanvas.tsx +30 -1
  23. package/corpus/templates/design/app/components/design/MultiScreenCanvas.tsx +14 -1
  24. package/corpus/templates/design/app/components/design/bridge/editor-chrome.bridge.ts +547 -50
  25. package/corpus/templates/design/app/components/design/dnd-debug.ts +27 -0
  26. package/corpus/templates/design/app/components/design/multi-screen/draft-primitives.ts +19 -2
  27. package/corpus/templates/design/app/i18n-data.ts +19 -0
  28. package/corpus/templates/design/app/lib/design-save-outbox.ts +46 -2
  29. package/corpus/templates/design/app/pages/design-editor/canvas-primitive-insert.ts +4 -9
  30. package/corpus/templates/design/app/pages/design-editor/history.ts +14 -1
  31. package/corpus/templates/design/changelog/2026-07-17-drawn-shapes-stay-free-positioned-when-dragged.md +6 -0
  32. package/corpus/templates/design/changelog/2026-07-17-shapes-show-a-live-outline-while-you-draw.md +6 -0
  33. package/corpus/templates/design/shared/drag-reflow.ts +375 -0
  34. package/corpus/templates/design/shared/full-app.ts +1 -1
  35. package/corpus/templates/dispatch/.agents/skills/feature-flags/SKILL.md +1 -1
  36. package/corpus/templates/forms/.agents/skills/feature-flags/SKILL.md +1 -1
  37. package/corpus/templates/macros/.agents/skills/feature-flags/SKILL.md +1 -1
  38. package/corpus/templates/mail/.agents/skills/feature-flags/SKILL.md +1 -1
  39. package/corpus/templates/plan/.agents/skills/feature-flags/SKILL.md +1 -1
  40. package/corpus/templates/slides/.agents/skills/feature-flags/SKILL.md +1 -1
  41. package/corpus/templates/tasks/.agents/skills/feature-flags/SKILL.md +1 -1
  42. package/dist/collab/routes.d.ts +1 -1
  43. package/dist/collab/struct-routes.d.ts +1 -1
  44. package/dist/db/request-telemetry.d.ts.map +1 -1
  45. package/dist/db/request-telemetry.js +24 -6
  46. package/dist/db/request-telemetry.js.map +1 -1
  47. package/dist/file-upload/actions/upload-image.d.ts +1 -1
  48. package/dist/notifications/routes.d.ts +1 -1
  49. package/dist/observability/routes.d.ts +3 -3
  50. package/dist/server/agent-engine-api-key-route.d.ts +1 -1
  51. package/dist/server/transcribe-voice.d.ts +1 -1
  52. package/dist/settings/store.d.ts +1 -1
  53. package/dist/settings/store.d.ts.map +1 -1
  54. package/dist/settings/store.js +14 -6
  55. package/dist/settings/store.js.map +1 -1
  56. package/dist/shared/optional-node-builtins.d.ts +23 -0
  57. package/dist/shared/optional-node-builtins.d.ts.map +1 -0
  58. package/dist/shared/optional-node-builtins.js +35 -0
  59. package/dist/shared/optional-node-builtins.js.map +1 -0
  60. package/dist/templates/chat/.agents/skills/feature-flags/SKILL.md +1 -1
  61. package/dist/templates/default/.agents/skills/feature-flags/SKILL.md +1 -1
  62. package/dist/templates/headless/.agents/skills/feature-flags/SKILL.md +1 -1
  63. package/dist/templates/workspace-core/.agents/skills/feature-flags/SKILL.md +1 -1
  64. package/dist/vite/client.d.ts.map +1 -1
  65. package/dist/vite/client.js +2 -0
  66. package/dist/vite/client.js.map +1 -1
  67. package/package.json +2 -1
  68. package/src/db/request-telemetry.ts +32 -8
  69. package/src/settings/store.ts +15 -6
  70. package/src/shared/optional-node-builtins.ts +66 -0
  71. package/src/templates/chat/.agents/skills/feature-flags/SKILL.md +1 -1
  72. package/src/templates/default/.agents/skills/feature-flags/SKILL.md +1 -1
  73. package/src/templates/headless/.agents/skills/feature-flags/SKILL.md +1 -1
  74. package/src/templates/workspace-core/.agents/skills/feature-flags/SKILL.md +1 -1
  75. package/src/vite/client.ts +5 -0
@@ -37,7 +37,7 @@ Keep definitions in a shared TypeScript module so server and client code use the
37
37
  same stable key. Flags are boolean and default-off.
38
38
 
39
39
  ```ts
40
- import { defineFeatureFlag } from "@agent-native/core/feature-flags";
40
+ import { defineFeatureFlag } from "@agent-native/core/feature-flags/registry";
41
41
 
42
42
  export const FULL_APP_BUILDING = defineFeatureFlag({
43
43
  key: "full-app-building",
@@ -37,7 +37,7 @@ Keep definitions in a shared TypeScript module so server and client code use the
37
37
  same stable key. Flags are boolean and default-off.
38
38
 
39
39
  ```ts
40
- import { defineFeatureFlag } from "@agent-native/core/feature-flags";
40
+ import { defineFeatureFlag } from "@agent-native/core/feature-flags/registry";
41
41
 
42
42
  export const FULL_APP_BUILDING = defineFeatureFlag({
43
43
  key: "full-app-building",
@@ -37,7 +37,7 @@ Keep definitions in a shared TypeScript module so server and client code use the
37
37
  same stable key. Flags are boolean and default-off.
38
38
 
39
39
  ```ts
40
- import { defineFeatureFlag } from "@agent-native/core/feature-flags";
40
+ import { defineFeatureFlag } from "@agent-native/core/feature-flags/registry";
41
41
 
42
42
  export const FULL_APP_BUILDING = defineFeatureFlag({
43
43
  key: "full-app-building",
@@ -37,7 +37,7 @@ Keep definitions in a shared TypeScript module so server and client code use the
37
37
  same stable key. Flags are boolean and default-off.
38
38
 
39
39
  ```ts
40
- import { defineFeatureFlag } from "@agent-native/core/feature-flags";
40
+ import { defineFeatureFlag } from "@agent-native/core/feature-flags/registry";
41
41
 
42
42
  export const FULL_APP_BUILDING = defineFeatureFlag({
43
43
  key: "full-app-building",
@@ -37,7 +37,7 @@ Keep definitions in a shared TypeScript module so server and client code use the
37
37
  same stable key. Flags are boolean and default-off.
38
38
 
39
39
  ```ts
40
- import { defineFeatureFlag } from "@agent-native/core/feature-flags";
40
+ import { defineFeatureFlag } from "@agent-native/core/feature-flags/registry";
41
41
 
42
42
  export const FULL_APP_BUILDING = defineFeatureFlag({
43
43
  key: "full-app-building",
@@ -37,7 +37,7 @@ Keep definitions in a shared TypeScript module so server and client code use the
37
37
  same stable key. Flags are boolean and default-off.
38
38
 
39
39
  ```ts
40
- import { defineFeatureFlag } from "@agent-native/core/feature-flags";
40
+ import { defineFeatureFlag } from "@agent-native/core/feature-flags/registry";
41
41
 
42
42
  export const FULL_APP_BUILDING = defineFeatureFlag({
43
43
  key: "full-app-building",
@@ -37,7 +37,7 @@ Keep definitions in a shared TypeScript module so server and client code use the
37
37
  same stable key. Flags are boolean and default-off.
38
38
 
39
39
  ```ts
40
- import { defineFeatureFlag } from "@agent-native/core/feature-flags";
40
+ import { defineFeatureFlag } from "@agent-native/core/feature-flags/registry";
41
41
 
42
42
  export const FULL_APP_BUILDING = defineFeatureFlag({
43
43
  key: "full-app-building",
@@ -26,8 +26,8 @@ export declare const getCollabState: import("h3").EventHandlerWithFetch<import("
26
26
  * Body: { update: string (base64), requestSource?: string }
27
27
  */
28
28
  export declare const postCollabUpdate: import("h3").EventHandlerWithFetch<import("h3").EventHandlerRequest, Promise<{
29
- error: string;
30
29
  ok?: undefined;
30
+ error: string;
31
31
  } | {
32
32
  error?: undefined;
33
33
  ok: boolean;
@@ -13,8 +13,8 @@
13
13
  * Body: { json: any, fieldName?: string, type?: "map"|"array", requestSource?: string }
14
14
  */
15
15
  export declare const postCollabJson: import("h3").EventHandlerWithFetch<import("h3").EventHandlerRequest, Promise<{
16
- ok?: undefined;
17
16
  error: string;
17
+ ok?: undefined;
18
18
  } | {
19
19
  error?: undefined;
20
20
  ok: boolean;
@@ -1 +1 @@
1
- {"version":3,"file":"request-telemetry.d.ts","sourceRoot":"","sources":["../../src/db/request-telemetry.ts"],"names":[],"mappings":"AAEA,MAAM,MAAM,qBAAqB,GAAG,SAAS,GAAG,OAAO,CAAC;AAExD,MAAM,WAAW,wBAAwB;IACvC,cAAc,EAAE,MAAM,CAAC;IACvB,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;IACrB,gBAAgB,EAAE,MAAM,CAAC;IACzB,eAAe,EAAE,MAAM,CAAC;IACxB,YAAY,EAAE,MAAM,CAAC;IACrB,cAAc,EAAE,MAAM,CAAC;IACvB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,oBAAoB,EAAE,MAAM,CAAC;IAC7B,qBAAqB,CAAC,EAAE,MAAM,CAAC;CAChC;AAwBD,wBAAgB,8BAA8B,IAAI,wBAAwB,CAezE;AAmBD,wBAAgB,6BAA6B,IACzC,wBAAwB,GACxB,SAAS,CAIZ;AAED,wBAAgB,+BAA+B,CAAC,CAAC,EAC/C,SAAS,EAAE,wBAAwB,EACnC,EAAE,EAAE,MAAM,CAAC,GACV,CAAC,CAEH;AAED,wBAAgB,6BAA6B,CAC3C,SAAS,EAAE,wBAAwB,GAClC,IAAI,CAEN;AAED,wBAAgB,sBAAsB,CACpC,SAAS,EAAE,qBAAqB,GAC/B,CAAC,OAAO,EAAE,SAAS,GAAG,OAAO,GAAG,SAAS,KAAK,IAAI,CAiDpD;AAED,wBAAgB,mBAAmB,IAAI,IAAI,CAG1C"}
1
+ {"version":3,"file":"request-telemetry.d.ts","sourceRoot":"","sources":["../../src/db/request-telemetry.ts"],"names":[],"mappings":"AAEA,MAAM,MAAM,qBAAqB,GAAG,SAAS,GAAG,OAAO,CAAC;AAExD,MAAM,WAAW,wBAAwB;IACvC,cAAc,EAAE,MAAM,CAAC;IACvB,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;IACrB,gBAAgB,EAAE,MAAM,CAAC;IACzB,eAAe,EAAE,MAAM,CAAC;IACxB,YAAY,EAAE,MAAM,CAAC;IACrB,cAAc,EAAE,MAAM,CAAC;IACvB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,oBAAoB,EAAE,MAAM,CAAC;IAC7B,qBAAqB,CAAC,EAAE,MAAM,CAAC;CAChC;AAgDD,wBAAgB,8BAA8B,IAAI,wBAAwB,CAezE;AAmBD,wBAAgB,6BAA6B,IACzC,wBAAwB,GACxB,SAAS,CAIZ;AAED,wBAAgB,+BAA+B,CAAC,CAAC,EAC/C,SAAS,EAAE,wBAAwB,EACnC,EAAE,EAAE,MAAM,CAAC,GACV,CAAC,CAEH;AAED,wBAAgB,6BAA6B,CAC3C,SAAS,EAAE,wBAAwB,GAClC,IAAI,CAEN;AAED,wBAAgB,sBAAsB,CACpC,SAAS,EAAE,qBAAqB,GAC/B,CAAC,OAAO,EAAE,SAAS,GAAG,OAAO,GAAG,SAAS,KAAK,IAAI,CAiDpD;AAED,wBAAgB,mBAAmB,IAAI,IAAI,CAG1C"}
@@ -1,10 +1,28 @@
1
- import { AsyncLocalStorage } from "node:async_hooks";
1
+ import { getAsyncLocalStorageCtor } from "../shared/optional-node-builtins.js";
2
2
  const STORAGE_KEY = Symbol.for("@agent-native/core/db.request-telemetry-storage");
3
3
  const STARTUP_STATE_KEY = Symbol.for("@agent-native/core/db.startup-telemetry-state");
4
4
  const STARTUP_CAPTURE_WINDOW_MS = 120_000;
5
5
  const globalRef = globalThis;
6
- const storage = globalRef[STORAGE_KEY] ??
7
- (globalRef[STORAGE_KEY] = new AsyncLocalStorage());
6
+ // AsyncLocalStorage is resolved lazily, never at module load: this module can
7
+ // land in the browser dev graph, where a top-level `new AsyncLocalStorage()`
8
+ // would throw against Vite's externalized `node:async_hooks` stub. On non-Node
9
+ // runtimes telemetry no-ops.
10
+ const NOOP_STORAGE = {
11
+ getStore: () => undefined,
12
+ run: (_store, fn) => fn(),
13
+ enterWith: () => { },
14
+ };
15
+ function getStorage() {
16
+ const existing = globalRef[STORAGE_KEY];
17
+ if (existing)
18
+ return existing;
19
+ const Ctor = getAsyncLocalStorageCtor();
20
+ const created = Ctor
21
+ ? new Ctor()
22
+ : NOOP_STORAGE;
23
+ globalRef[STORAGE_KEY] = created;
24
+ return created;
25
+ }
8
26
  export function createDatabaseRequestTelemetry() {
9
27
  return {
10
28
  operationCount: 0,
@@ -28,7 +46,7 @@ const startupState = globalRef[STARTUP_STATE_KEY] ??
28
46
  telemetry: createDatabaseRequestTelemetry(),
29
47
  });
30
48
  function currentDatabaseTelemetry() {
31
- const requestTelemetry = storage.getStore();
49
+ const requestTelemetry = getStorage().getStore();
32
50
  if (requestTelemetry)
33
51
  return requestTelemetry;
34
52
  if (!startupState.claimed && Date.now() <= startupState.captureUntil) {
@@ -43,10 +61,10 @@ export function claimStartupDatabaseTelemetry() {
43
61
  return startupState.telemetry;
44
62
  }
45
63
  export function runWithDatabaseRequestTelemetry(telemetry, fn) {
46
- return storage.run(telemetry, fn);
64
+ return getStorage().run(telemetry, fn);
47
65
  }
48
66
  export function enterDatabaseRequestTelemetry(telemetry) {
49
- storage.enterWith(telemetry);
67
+ getStorage().enterWith(telemetry);
50
68
  }
51
69
  export function beginDatabaseOperation(operation) {
52
70
  const telemetry = currentDatabaseTelemetry();
@@ -1 +1 @@
1
- {"version":3,"file":"request-telemetry.js","sourceRoot":"","sources":["../../src/db/request-telemetry.ts"],"names":[],"mappings":"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","sourcesContent":["import { AsyncLocalStorage } from \"node:async_hooks\";\n\nexport type DatabaseOperationKind = \"connect\" | \"query\";\n\nexport interface DatabaseRequestTelemetry {\n operationCount: number;\n queryCount: number;\n connectCount: number;\n retryCount: number;\n errorCount: number;\n timeoutCount: number;\n operationTotalMs: number;\n operationWallMs: number;\n queryTotalMs: number;\n connectTotalMs: number;\n slowestOperationMs: number;\n activeOperationCount: number;\n activeWindowStartedAt?: number;\n}\n\nconst STORAGE_KEY = Symbol.for(\n \"@agent-native/core/db.request-telemetry-storage\",\n);\nconst STARTUP_STATE_KEY = Symbol.for(\n \"@agent-native/core/db.startup-telemetry-state\",\n);\nconst STARTUP_CAPTURE_WINDOW_MS = 120_000;\ninterface StartupDatabaseTelemetryState {\n captureUntil: number;\n claimed: boolean;\n telemetry: DatabaseRequestTelemetry;\n}\ntype GlobalWithDatabaseTelemetry = typeof globalThis & {\n [STORAGE_KEY]?: AsyncLocalStorage<DatabaseRequestTelemetry>;\n [STARTUP_STATE_KEY]?: StartupDatabaseTelemetryState;\n};\n\nconst globalRef = globalThis as GlobalWithDatabaseTelemetry;\nconst storage =\n globalRef[STORAGE_KEY] ??\n (globalRef[STORAGE_KEY] = new AsyncLocalStorage<DatabaseRequestTelemetry>());\n\nexport function createDatabaseRequestTelemetry(): DatabaseRequestTelemetry {\n return {\n operationCount: 0,\n queryCount: 0,\n connectCount: 0,\n retryCount: 0,\n errorCount: 0,\n timeoutCount: 0,\n operationTotalMs: 0,\n operationWallMs: 0,\n queryTotalMs: 0,\n connectTotalMs: 0,\n slowestOperationMs: 0,\n activeOperationCount: 0,\n };\n}\n\nconst startupState =\n globalRef[STARTUP_STATE_KEY] ??\n (globalRef[STARTUP_STATE_KEY] = {\n captureUntil: Date.now() + STARTUP_CAPTURE_WINDOW_MS,\n claimed: false,\n telemetry: createDatabaseRequestTelemetry(),\n });\n\nfunction currentDatabaseTelemetry(): DatabaseRequestTelemetry | undefined {\n const requestTelemetry = storage.getStore();\n if (requestTelemetry) return requestTelemetry;\n if (!startupState.claimed && Date.now() <= startupState.captureUntil) {\n return startupState.telemetry;\n }\n return undefined;\n}\n\nexport function claimStartupDatabaseTelemetry():\n | DatabaseRequestTelemetry\n | undefined {\n if (startupState.claimed) return undefined;\n startupState.claimed = true;\n return startupState.telemetry;\n}\n\nexport function runWithDatabaseRequestTelemetry<T>(\n telemetry: DatabaseRequestTelemetry,\n fn: () => T,\n): T {\n return storage.run(telemetry, fn);\n}\n\nexport function enterDatabaseRequestTelemetry(\n telemetry: DatabaseRequestTelemetry,\n): void {\n storage.enterWith(telemetry);\n}\n\nexport function beginDatabaseOperation(\n operation: DatabaseOperationKind,\n): (outcome: \"success\" | \"error\" | \"timeout\") => void {\n const telemetry = currentDatabaseTelemetry();\n if (!telemetry) return () => {};\n\n const startedAt = Date.now();\n if (telemetry.activeOperationCount === 0) {\n telemetry.activeWindowStartedAt = startedAt;\n }\n telemetry.activeOperationCount += 1;\n let completed = false;\n\n return (outcome) => {\n if (completed) return;\n completed = true;\n const completedAt = Date.now();\n const duration = Math.max(0, completedAt - startedAt);\n telemetry.operationCount += 1;\n telemetry.operationTotalMs += duration;\n telemetry.slowestOperationMs = Math.max(\n telemetry.slowestOperationMs,\n duration,\n );\n\n if (operation === \"connect\") {\n telemetry.connectCount += 1;\n telemetry.connectTotalMs += duration;\n } else {\n telemetry.queryCount += 1;\n telemetry.queryTotalMs += duration;\n }\n\n if (outcome !== \"success\") telemetry.errorCount += 1;\n if (outcome === \"timeout\") telemetry.timeoutCount += 1;\n\n telemetry.activeOperationCount = Math.max(\n 0,\n telemetry.activeOperationCount - 1,\n );\n if (\n telemetry.activeOperationCount === 0 &&\n telemetry.activeWindowStartedAt !== undefined\n ) {\n telemetry.operationWallMs += Math.max(\n 0,\n completedAt - telemetry.activeWindowStartedAt,\n );\n telemetry.activeWindowStartedAt = undefined;\n }\n };\n}\n\nexport function recordDatabaseRetry(): void {\n const telemetry = currentDatabaseTelemetry();\n if (telemetry) telemetry.retryCount += 1;\n}\n"]}
1
+ {"version":3,"file":"request-telemetry.js","sourceRoot":"","sources":["../../src/db/request-telemetry.ts"],"names":[],"mappings":"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","sourcesContent":["import { getAsyncLocalStorageCtor } from \"../shared/optional-node-builtins.js\";\n\nexport type DatabaseOperationKind = \"connect\" | \"query\";\n\nexport interface DatabaseRequestTelemetry {\n operationCount: number;\n queryCount: number;\n connectCount: number;\n retryCount: number;\n errorCount: number;\n timeoutCount: number;\n operationTotalMs: number;\n operationWallMs: number;\n queryTotalMs: number;\n connectTotalMs: number;\n slowestOperationMs: number;\n activeOperationCount: number;\n activeWindowStartedAt?: number;\n}\n\nconst STORAGE_KEY = Symbol.for(\n \"@agent-native/core/db.request-telemetry-storage\",\n);\nconst STARTUP_STATE_KEY = Symbol.for(\n \"@agent-native/core/db.startup-telemetry-state\",\n);\nconst STARTUP_CAPTURE_WINDOW_MS = 120_000;\ninterface StartupDatabaseTelemetryState {\n captureUntil: number;\n claimed: boolean;\n telemetry: DatabaseRequestTelemetry;\n}\ninterface TelemetryStorage {\n getStore(): DatabaseRequestTelemetry | undefined;\n run<T>(store: DatabaseRequestTelemetry, fn: () => T): T;\n enterWith(store: DatabaseRequestTelemetry): void;\n}\n\ntype GlobalWithDatabaseTelemetry = typeof globalThis & {\n [STORAGE_KEY]?: TelemetryStorage;\n [STARTUP_STATE_KEY]?: StartupDatabaseTelemetryState;\n};\n\nconst globalRef = globalThis as GlobalWithDatabaseTelemetry;\n\n// AsyncLocalStorage is resolved lazily, never at module load: this module can\n// land in the browser dev graph, where a top-level `new AsyncLocalStorage()`\n// would throw against Vite's externalized `node:async_hooks` stub. On non-Node\n// runtimes telemetry no-ops.\nconst NOOP_STORAGE: TelemetryStorage = {\n getStore: () => undefined,\n run: (_store, fn) => fn(),\n enterWith: () => {},\n};\n\nfunction getStorage(): TelemetryStorage {\n const existing = globalRef[STORAGE_KEY];\n if (existing) return existing;\n const Ctor = getAsyncLocalStorageCtor();\n const created: TelemetryStorage = Ctor\n ? new Ctor<DatabaseRequestTelemetry>()\n : NOOP_STORAGE;\n globalRef[STORAGE_KEY] = created;\n return created;\n}\n\nexport function createDatabaseRequestTelemetry(): DatabaseRequestTelemetry {\n return {\n operationCount: 0,\n queryCount: 0,\n connectCount: 0,\n retryCount: 0,\n errorCount: 0,\n timeoutCount: 0,\n operationTotalMs: 0,\n operationWallMs: 0,\n queryTotalMs: 0,\n connectTotalMs: 0,\n slowestOperationMs: 0,\n activeOperationCount: 0,\n };\n}\n\nconst startupState =\n globalRef[STARTUP_STATE_KEY] ??\n (globalRef[STARTUP_STATE_KEY] = {\n captureUntil: Date.now() + STARTUP_CAPTURE_WINDOW_MS,\n claimed: false,\n telemetry: createDatabaseRequestTelemetry(),\n });\n\nfunction currentDatabaseTelemetry(): DatabaseRequestTelemetry | undefined {\n const requestTelemetry = getStorage().getStore();\n if (requestTelemetry) return requestTelemetry;\n if (!startupState.claimed && Date.now() <= startupState.captureUntil) {\n return startupState.telemetry;\n }\n return undefined;\n}\n\nexport function claimStartupDatabaseTelemetry():\n | DatabaseRequestTelemetry\n | undefined {\n if (startupState.claimed) return undefined;\n startupState.claimed = true;\n return startupState.telemetry;\n}\n\nexport function runWithDatabaseRequestTelemetry<T>(\n telemetry: DatabaseRequestTelemetry,\n fn: () => T,\n): T {\n return getStorage().run(telemetry, fn);\n}\n\nexport function enterDatabaseRequestTelemetry(\n telemetry: DatabaseRequestTelemetry,\n): void {\n getStorage().enterWith(telemetry);\n}\n\nexport function beginDatabaseOperation(\n operation: DatabaseOperationKind,\n): (outcome: \"success\" | \"error\" | \"timeout\") => void {\n const telemetry = currentDatabaseTelemetry();\n if (!telemetry) return () => {};\n\n const startedAt = Date.now();\n if (telemetry.activeOperationCount === 0) {\n telemetry.activeWindowStartedAt = startedAt;\n }\n telemetry.activeOperationCount += 1;\n let completed = false;\n\n return (outcome) => {\n if (completed) return;\n completed = true;\n const completedAt = Date.now();\n const duration = Math.max(0, completedAt - startedAt);\n telemetry.operationCount += 1;\n telemetry.operationTotalMs += duration;\n telemetry.slowestOperationMs = Math.max(\n telemetry.slowestOperationMs,\n duration,\n );\n\n if (operation === \"connect\") {\n telemetry.connectCount += 1;\n telemetry.connectTotalMs += duration;\n } else {\n telemetry.queryCount += 1;\n telemetry.queryTotalMs += duration;\n }\n\n if (outcome !== \"success\") telemetry.errorCount += 1;\n if (outcome === \"timeout\") telemetry.timeoutCount += 1;\n\n telemetry.activeOperationCount = Math.max(\n 0,\n telemetry.activeOperationCount - 1,\n );\n if (\n telemetry.activeOperationCount === 0 &&\n telemetry.activeWindowStartedAt !== undefined\n ) {\n telemetry.operationWallMs += Math.max(\n 0,\n completedAt - telemetry.activeWindowStartedAt,\n );\n telemetry.activeWindowStartedAt = undefined;\n }\n };\n}\n\nexport function recordDatabaseRetry(): void {\n const telemetry = currentDatabaseTelemetry();\n if (telemetry) telemetry.retryCount += 1;\n}\n"]}
@@ -17,12 +17,12 @@ declare const _default: import("../../action.js").ActionDefinition<{
17
17
  id?: undefined;
18
18
  provider?: undefined;
19
19
  } | {
20
- error?: undefined;
21
20
  configured?: undefined;
22
21
  connectPath?: undefined;
23
22
  url: string;
24
23
  id: string;
25
24
  provider: string;
25
+ error?: undefined;
26
26
  }>;
27
27
  export default _default;
28
28
  //# sourceMappingURL=upload-image.d.ts.map
@@ -28,7 +28,7 @@ export declare function createNotificationsHandler(): import("h3").EventHandlerW
28
28
  } | {
29
29
  count?: undefined;
30
30
  updated?: undefined;
31
- ok: boolean;
32
31
  error?: undefined;
32
+ ok: boolean;
33
33
  }>>;
34
34
  //# sourceMappingURL=routes.d.ts.map
@@ -41,16 +41,16 @@ export declare function createObservabilityHandler(): import("h3").EventHandlerW
41
41
  thumbsUpRate: number;
42
42
  avgEvalScore: number;
43
43
  } | {
44
- error?: undefined;
45
44
  summary: import("./types.js").TraceSummary;
46
45
  spans: import("./types.js").TraceSpan[];
47
46
  id?: undefined;
47
+ error?: undefined;
48
48
  ok?: undefined;
49
49
  } | {
50
- error?: undefined;
51
50
  summary?: undefined;
52
51
  spans?: undefined;
53
52
  id: string;
53
+ error?: undefined;
54
54
  ok?: undefined;
55
55
  } | {
56
56
  summary?: undefined;
@@ -59,10 +59,10 @@ export declare function createObservabilityHandler(): import("h3").EventHandlerW
59
59
  error: any;
60
60
  ok?: undefined;
61
61
  } | {
62
- error?: undefined;
63
62
  summary?: undefined;
64
63
  spans?: undefined;
65
64
  id?: undefined;
65
+ error?: undefined;
66
66
  ok: boolean;
67
67
  }>>;
68
68
  //# sourceMappingURL=routes.d.ts.map
@@ -27,11 +27,11 @@ export declare function resolveAgentEngineApiKeyWriteTarget(event: H3Event, scop
27
27
  export declare function createAgentEngineApiKeyHandler(): import("h3").EventHandlerWithFetch<import("h3").EventHandlerRequest, Promise<{
28
28
  error: any;
29
29
  } | {
30
+ error?: undefined;
30
31
  ok: boolean;
31
32
  key: string;
32
33
  baseUrlKey?: string;
33
34
  scope: AgentEngineApiKeyScope;
34
- error?: undefined;
35
35
  }>>;
36
36
  export {};
37
37
  //# sourceMappingURL=agent-engine-api-key-route.d.ts.map
@@ -20,7 +20,7 @@ export declare function createTranscribeVoiceHandler(): import("h3").EventHandle
20
20
  error: string;
21
21
  text?: undefined;
22
22
  } | {
23
- error?: undefined;
24
23
  text: string;
24
+ error?: undefined;
25
25
  }>>;
26
26
  //# sourceMappingURL=transcribe-voice.d.ts.map
@@ -1,4 +1,4 @@
1
- import { EventEmitter } from "events";
1
+ import type { EventEmitter } from "node:events";
2
2
  export declare function getSettingsEmitter(): EventEmitter;
3
3
  export declare function getSetting(key: string): Promise<Record<string, unknown> | null>;
4
4
  export interface StoreWriteOptions {
@@ -1 +1 @@
1
- {"version":3,"file":"store.d.ts","sourceRoot":"","sources":["../../src/settings/store.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,QAAQ,CAAC;AAiCtC,wBAAgB,kBAAkB,IAAI,YAAY,CAEjD;AAsED,wBAAsB,UAAU,CAC9B,GAAG,EAAE,MAAM,GACV,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC,CAgBzC;AAED,MAAM,WAAW,iBAAiB;IAChC,gEAAgE;IAChE,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAID;;;;;;GAMG;AACH,wBAAsB,aAAa,CACjC,GAAG,EAAE,MAAM,EACX,OAAO,EAAE,CACP,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,KACpC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,EAC/D,OAAO,CAAC,EAAE,iBAAiB,GAC1B,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAwClC;AAED,wBAAsB,UAAU,CAC9B,GAAG,EAAE,MAAM,EACX,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC9B,OAAO,CAAC,EAAE,iBAAiB,GAC1B,OAAO,CAAC,IAAI,CAAC,CAiBf;AAED,wBAAsB,aAAa,CACjC,GAAG,EAAE,MAAM,EACX,OAAO,CAAC,EAAE,iBAAiB,GAC1B,OAAO,CAAC,OAAO,CAAC,CAmBlB;AAED,wBAAsB,cAAc,IAAI,OAAO,CAC7C,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CACxC,CAUA"}
1
+ {"version":3,"file":"store.d.ts","sourceRoot":"","sources":["../../src/settings/store.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AA0ChD,wBAAgB,kBAAkB,IAAI,YAAY,CAEjD;AAsED,wBAAsB,UAAU,CAC9B,GAAG,EAAE,MAAM,GACV,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC,CAgBzC;AAED,MAAM,WAAW,iBAAiB;IAChC,gEAAgE;IAChE,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAID;;;;;;GAMG;AACH,wBAAsB,aAAa,CACjC,GAAG,EAAE,MAAM,EACX,OAAO,EAAE,CACP,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,KACpC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,EAC/D,OAAO,CAAC,EAAE,iBAAiB,GAC1B,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAwClC;AAED,wBAAsB,UAAU,CAC9B,GAAG,EAAE,MAAM,EACX,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC9B,OAAO,CAAC,EAAE,iBAAiB,GAC1B,OAAO,CAAC,IAAI,CAAC,CAiBf;AAED,wBAAsB,aAAa,CACjC,GAAG,EAAE,MAAM,EACX,OAAO,CAAC,EAAE,iBAAiB,GAC1B,OAAO,CAAC,OAAO,CAAC,CAmBlB;AAED,wBAAsB,cAAc,IAAI,OAAO,CAC7C,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CACxC,CAUA"}
@@ -1,8 +1,8 @@
1
- import { EventEmitter } from "events";
2
1
  import { getDbExec, isPostgres, intType } from "../db/client.js";
3
2
  import { ensureIndexExists, ensureTableExists } from "../db/ddl-guard.js";
4
3
  import { widenIntColumnsToBigInt } from "../db/widen-columns.js";
5
4
  import { getRequestContext } from "../server/request-context.js";
5
+ import { createEventEmitter } from "../shared/optional-node-builtins.js";
6
6
  let _initPromise;
7
7
  // Per-request memoization of settings reads, keyed on the active
8
8
  // AsyncLocalStorage RequestContext (WeakMap → freed with the request). One
@@ -25,10 +25,18 @@ function requestSettingsCache() {
25
25
  }
26
26
  return cache;
27
27
  }
28
- const _emitter = new EventEmitter();
29
- export function getSettingsEmitter() {
28
+ // Created lazily so this module can be evaluated in the browser dev graph
29
+ // without a top-level `new EventEmitter()` tripping Vite's externalized
30
+ // `node:events` stub. The emitter drives server-side SSE fan-out only.
31
+ let _emitter;
32
+ function settingsEmitter() {
33
+ if (!_emitter)
34
+ _emitter = createEventEmitter();
30
35
  return _emitter;
31
36
  }
37
+ export function getSettingsEmitter() {
38
+ return settingsEmitter();
39
+ }
32
40
  function settingsTable() {
33
41
  return isPostgres() ? "public.settings" : "settings";
34
42
  }
@@ -144,7 +152,7 @@ export async function mutateSetting(key, updater, options) {
144
152
  if (result.rowsAffected === 0)
145
153
  continue;
146
154
  requestSettingsCache()?.set(key, nextRaw);
147
- _emitter.emit("settings", {
155
+ settingsEmitter().emit("settings", {
148
156
  source: "settings",
149
157
  type: "change",
150
158
  key,
@@ -165,7 +173,7 @@ export async function putSetting(key, value, options) {
165
173
  args: [key, JSON.stringify(value), Date.now()],
166
174
  });
167
175
  requestSettingsCache()?.set(key, JSON.stringify(value));
168
- _emitter.emit("settings", {
176
+ settingsEmitter().emit("settings", {
169
177
  source: "settings",
170
178
  type: "change",
171
179
  key,
@@ -182,7 +190,7 @@ export async function deleteSetting(key, options) {
182
190
  });
183
191
  requestSettingsCache()?.set(key, null);
184
192
  if (result.rowsAffected > 0) {
185
- _emitter.emit("settings", {
193
+ settingsEmitter().emit("settings", {
186
194
  source: "settings",
187
195
  type: "delete",
188
196
  key,
@@ -1 +1 @@
1
- {"version":3,"file":"store.js","sourceRoot":"","sources":["../../src/settings/store.ts"],"names":[],"mappings":"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","sourcesContent":["import { EventEmitter } from \"events\";\n\nimport { getDbExec, isPostgres, intType } from \"../db/client.js\";\nimport { ensureIndexExists, ensureTableExists } from \"../db/ddl-guard.js\";\nimport { widenIntColumnsToBigInt } from \"../db/widen-columns.js\";\nimport { getRequestContext } from \"../server/request-context.js\";\n\nlet _initPromise: Promise<void> | undefined;\n\n// Per-request memoization of settings reads, keyed on the active\n// AsyncLocalStorage RequestContext (WeakMap → freed with the request). One\n// action request can read the same setting several times (org resolution,\n// guards, the action body), and each read is a network round trip on\n// serverless Postgres. Mirrors the per-request session/org caches on\n// event.context. The cache holds the raw JSON string and re-parses per hit\n// so callers can't mutate a shared object; writes in the same request are\n// written through, while other in-flight requests keep their snapshot for\n// their own (short) lifetime.\nconst _requestSettingsCache = new WeakMap<object, Map<string, string | null>>();\n\nfunction requestSettingsCache(): Map<string, string | null> | null {\n const ctx = getRequestContext();\n if (!ctx || typeof ctx !== \"object\") return null;\n let cache = _requestSettingsCache.get(ctx);\n if (!cache) {\n cache = new Map();\n _requestSettingsCache.set(ctx, cache);\n }\n return cache;\n}\n\nconst _emitter = new EventEmitter();\n\nexport function getSettingsEmitter(): EventEmitter {\n return _emitter;\n}\n\nfunction settingsTable(): string {\n return isPostgres() ? \"public.settings\" : \"settings\";\n}\n\nasync function ensureTable(): Promise<void> {\n if (!_initPromise) {\n _initPromise = (async () => {\n const client = getDbExec();\n const table = settingsTable();\n const createSql = `\n CREATE TABLE IF NOT EXISTS ${table} (\n key TEXT PRIMARY KEY,\n value TEXT NOT NULL,\n updated_at ${intType()} NOT NULL\n )\n `;\n\n if (isPostgres()) {\n // Hot path: the `settings` table and its poll index are virtually\n // always already present in production. Issuing `CREATE TABLE`/\n // `CREATE INDEX` still takes a lock that, in a fresh background-worker\n // process behind a concurrent connection on the shared Neon DB, can\n // block ~indefinitely (ACCESS EXCLUSIVE for CREATE TABLE; a write-\n // blocking SHARE lock for CREATE INDEX). `ensureTableExists` /\n // `ensureIndexExists` probe `information_schema`/`pg_indexes` first\n // (plain reads, no lock) and run DDL ONLY for what is actually missing,\n // bounding any DDL with a transaction-scoped `lock_timeout`. They also\n // re-probe after a swallowed lock-timeout and THROW if the schema is\n // still missing, so a timed-out DDL never poisons this init memo with\n // missing schema. `settingsTable()` is `public.settings` on Postgres;\n // the existence checks use the unqualified table name.\n await ensureTableExists(\"settings\", createSql);\n // Older deployments (pre BIGINT-compat) have a 32-bit `updated_at`; on\n // Postgres the `Date.now()` written on every setSetting overflows int4.\n // widenIntColumnsToBigInt already probes information_schema and only\n // ALTERs columns that are still int4 — a no-op on fresh/widened DBs.\n await widenIntColumnsToBigInt(\"settings\", [\"updated_at\"]);\n // Index for the poll watermark query: `SELECT MAX(updated_at)`.\n await ensureIndexExists(\n \"settings_updated_at_idx\",\n `CREATE INDEX IF NOT EXISTS settings_updated_at_idx ON ${table} (updated_at)`,\n );\n return;\n }\n\n // SQLite (local dev): no lock problem — keep the original behaviour.\n await client.execute(createSql);\n // No-op on SQLite (INTEGER is already 64-bit).\n await widenIntColumnsToBigInt(\"settings\", [\"updated_at\"]);\n // Index for the poll watermark query: `SELECT MAX(updated_at) FROM settings`.\n // MAX on an indexed column avoids a full-table scan on every poll cycle.\n // IF NOT EXISTS makes it idempotent on existing databases.\n try {\n await client.execute(\n `CREATE INDEX IF NOT EXISTS settings_updated_at_idx ON ${table} (updated_at)`,\n );\n } catch {\n // Index already exists or the dialect rejected a duplicate.\n }\n })().catch((err) => {\n // Retry init on the next call after a failed startup.\n _initPromise = undefined;\n throw err;\n });\n }\n return _initPromise;\n}\n\nexport async function getSetting(\n key: string,\n): Promise<Record<string, unknown> | null> {\n const cache = requestSettingsCache();\n if (cache?.has(key)) {\n const cached = cache.get(key);\n return cached == null ? null : JSON.parse(cached);\n }\n await ensureTable();\n const client = getDbExec();\n const table = settingsTable();\n const { rows } = await client.execute({\n sql: `SELECT value FROM ${table} WHERE key = ?`,\n args: [key],\n });\n const raw = rows.length === 0 ? null : (rows[0].value as string);\n cache?.set(key, raw);\n return raw == null ? null : JSON.parse(raw);\n}\n\nexport interface StoreWriteOptions {\n /** Tag identifying who initiated this write (e.g. a tab ID). */\n requestSource?: string;\n}\n\nconst SETTINGS_MUTATION_ATTEMPTS = 25;\n\n/**\n * Atomically derive and persist one setting with an optimistic raw-value CAS.\n * This works across SQLite/libSQL and Postgres and remains safe across\n * horizontally scaled processes where an in-memory mutex would not.\n * The updater may run more than once after contention and must not perform\n * external side effects.\n */\nexport async function mutateSetting(\n key: string,\n updater: (\n current: Record<string, unknown> | null,\n ) => Record<string, unknown> | Promise<Record<string, unknown>>,\n options?: StoreWriteOptions,\n): Promise<Record<string, unknown>> {\n await ensureTable();\n const client = getDbExec();\n const table = settingsTable();\n for (let attempt = 0; attempt < SETTINGS_MUTATION_ATTEMPTS; attempt += 1) {\n // Deliberately bypass the request cache: a failed CAS means another\n // request committed a newer value and the next attempt must reread it.\n const snapshot = await client.execute({\n sql: `SELECT value FROM ${table} WHERE key = ?`,\n args: [key],\n });\n const raw =\n snapshot.rows.length === 0 ? null : (snapshot.rows[0]?.value as string);\n const current = raw == null ? null : JSON.parse(raw);\n const next = await updater(current);\n const nextRaw = JSON.stringify(next);\n const timestamp = Date.now();\n const result =\n raw == null\n ? await client.execute({\n sql: isPostgres()\n ? `INSERT INTO ${table} (key, value, updated_at) VALUES (?, ?, ?) ON CONFLICT (key) DO NOTHING`\n : `INSERT OR IGNORE INTO ${table} (key, value, updated_at) VALUES (?, ?, ?)`,\n args: [key, nextRaw, timestamp],\n })\n : await client.execute({\n sql: `UPDATE ${table} SET value = ?, updated_at = ? WHERE key = ? AND value = ?`,\n args: [nextRaw, timestamp, key, raw],\n });\n if (result.rowsAffected === 0) continue;\n requestSettingsCache()?.set(key, nextRaw);\n _emitter.emit(\"settings\", {\n source: \"settings\",\n type: \"change\",\n key,\n ...(options?.requestSource && { requestSource: options.requestSource }),\n });\n return JSON.parse(nextRaw);\n }\n throw new Error(`Setting ${key} changed too many times; retry the mutation.`);\n}\n\nexport async function putSetting(\n key: string,\n value: Record<string, unknown>,\n options?: StoreWriteOptions,\n): Promise<void> {\n await ensureTable();\n const client = getDbExec();\n const table = settingsTable();\n await client.execute({\n sql: isPostgres()\n ? `INSERT INTO ${table} (key, value, updated_at) VALUES (?, ?, ?) ON CONFLICT (key) DO UPDATE SET value=EXCLUDED.value, updated_at=EXCLUDED.updated_at`\n : `INSERT OR REPLACE INTO ${table} (key, value, updated_at) VALUES (?, ?, ?)`,\n args: [key, JSON.stringify(value), Date.now()],\n });\n requestSettingsCache()?.set(key, JSON.stringify(value));\n _emitter.emit(\"settings\", {\n source: \"settings\",\n type: \"change\",\n key,\n ...(options?.requestSource && { requestSource: options.requestSource }),\n });\n}\n\nexport async function deleteSetting(\n key: string,\n options?: StoreWriteOptions,\n): Promise<boolean> {\n await ensureTable();\n const client = getDbExec();\n const table = settingsTable();\n const result = await client.execute({\n sql: `DELETE FROM ${table} WHERE key = ?`,\n args: [key],\n });\n requestSettingsCache()?.set(key, null);\n if (result.rowsAffected > 0) {\n _emitter.emit(\"settings\", {\n source: \"settings\",\n type: \"delete\",\n key,\n ...(options?.requestSource && { requestSource: options.requestSource }),\n });\n return true;\n }\n return false;\n}\n\nexport async function getAllSettings(): Promise<\n Record<string, Record<string, unknown>>\n> {\n await ensureTable();\n const client = getDbExec();\n const table = settingsTable();\n const { rows } = await client.execute(`SELECT key, value FROM ${table}`);\n const result: Record<string, Record<string, unknown>> = {};\n for (const row of rows) {\n result[row.key as string] = JSON.parse(row.value as string);\n }\n return result;\n}\n"]}
1
+ {"version":3,"file":"store.js","sourceRoot":"","sources":["../../src/settings/store.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,SAAS,EAAE,UAAU,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAC;AACjE,OAAO,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AAC1E,OAAO,EAAE,uBAAuB,EAAE,MAAM,wBAAwB,CAAC;AACjE,OAAO,EAAE,iBAAiB,EAAE,MAAM,8BAA8B,CAAC;AACjE,OAAO,EAAE,kBAAkB,EAAE,MAAM,qCAAqC,CAAC;AAEzE,IAAI,YAAuC,CAAC;AAE5C,iEAAiE;AACjE,2EAA2E;AAC3E,0EAA0E;AAC1E,qEAAqE;AACrE,qEAAqE;AACrE,2EAA2E;AAC3E,0EAA0E;AAC1E,0EAA0E;AAC1E,8BAA8B;AAC9B,MAAM,qBAAqB,GAAG,IAAI,OAAO,EAAsC,CAAC;AAEhF,SAAS,oBAAoB;IAC3B,MAAM,GAAG,GAAG,iBAAiB,EAAE,CAAC;IAChC,IAAI,CAAC,GAAG,IAAI,OAAO,GAAG,KAAK,QAAQ;QAAE,OAAO,IAAI,CAAC;IACjD,IAAI,KAAK,GAAG,qBAAqB,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IAC3C,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,KAAK,GAAG,IAAI,GAAG,EAAE,CAAC;QAClB,qBAAqB,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;IACxC,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED,0EAA0E;AAC1E,wEAAwE;AACxE,uEAAuE;AACvE,IAAI,QAAkC,CAAC;AAEvC,SAAS,eAAe;IACtB,IAAI,CAAC,QAAQ;QAAE,QAAQ,GAAG,kBAAkB,EAAE,CAAC;IAC/C,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED,MAAM,UAAU,kBAAkB;IAChC,OAAO,eAAe,EAAE,CAAC;AAC3B,CAAC;AAED,SAAS,aAAa;IACpB,OAAO,UAAU,EAAE,CAAC,CAAC,CAAC,iBAAiB,CAAC,CAAC,CAAC,UAAU,CAAC;AACvD,CAAC;AAED,KAAK,UAAU,WAAW;IACxB,IAAI,CAAC,YAAY,EAAE,CAAC;QAClB,YAAY,GAAG,CAAC,KAAK,IAAI,EAAE;YACzB,MAAM,MAAM,GAAG,SAAS,EAAE,CAAC;YAC3B,MAAM,KAAK,GAAG,aAAa,EAAE,CAAC;YAC9B,MAAM,SAAS,GAAG;qCACa,KAAK;;;uBAGnB,OAAO,EAAE;;OAEzB,CAAC;YAEF,IAAI,UAAU,EAAE,EAAE,CAAC;gBACjB,kEAAkE;gBAClE,gEAAgE;gBAChE,uEAAuE;gBACvE,oEAAoE;gBACpE,mEAAmE;gBACnE,+DAA+D;gBAC/D,oEAAoE;gBACpE,wEAAwE;gBACxE,uEAAuE;gBACvE,qEAAqE;gBACrE,sEAAsE;gBACtE,sEAAsE;gBACtE,uDAAuD;gBACvD,MAAM,iBAAiB,CAAC,UAAU,EAAE,SAAS,CAAC,CAAC;gBAC/C,uEAAuE;gBACvE,wEAAwE;gBACxE,qEAAqE;gBACrE,qEAAqE;gBACrE,MAAM,uBAAuB,CAAC,UAAU,EAAE,CAAC,YAAY,CAAC,CAAC,CAAC;gBAC1D,gEAAgE;gBAChE,MAAM,iBAAiB,CACrB,yBAAyB,EACzB,yDAAyD,KAAK,eAAe,CAC9E,CAAC;gBACF,OAAO;YACT,CAAC;YAED,qEAAqE;YACrE,MAAM,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;YAChC,+CAA+C;YAC/C,MAAM,uBAAuB,CAAC,UAAU,EAAE,CAAC,YAAY,CAAC,CAAC,CAAC;YAC1D,8EAA8E;YAC9E,yEAAyE;YACzE,2DAA2D;YAC3D,IAAI,CAAC;gBACH,MAAM,MAAM,CAAC,OAAO,CAClB,yDAAyD,KAAK,eAAe,CAC9E,CAAC;YACJ,CAAC;YAAC,MAAM,CAAC;gBACP,4DAA4D;YAC9D,CAAC;QACH,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE;YACjB,sDAAsD;YACtD,YAAY,GAAG,SAAS,CAAC;YACzB,MAAM,GAAG,CAAC;QACZ,CAAC,CAAC,CAAC;IACL,CAAC;IACD,OAAO,YAAY,CAAC;AACtB,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,UAAU,CAC9B,GAAW;IAEX,MAAM,KAAK,GAAG,oBAAoB,EAAE,CAAC;IACrC,IAAI,KAAK,EAAE,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC;QACpB,MAAM,MAAM,GAAG,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QAC9B,OAAO,MAAM,IAAI,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;IACpD,CAAC;IACD,MAAM,WAAW,EAAE,CAAC;IACpB,MAAM,MAAM,GAAG,SAAS,EAAE,CAAC;IAC3B,MAAM,KAAK,GAAG,aAAa,EAAE,CAAC;IAC9B,MAAM,EAAE,IAAI,EAAE,GAAG,MAAM,MAAM,CAAC,OAAO,CAAC;QACpC,GAAG,EAAE,qBAAqB,KAAK,gBAAgB;QAC/C,IAAI,EAAE,CAAC,GAAG,CAAC;KACZ,CAAC,CAAC;IACH,MAAM,GAAG,GAAG,IAAI,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAE,IAAI,CAAC,CAAC,CAAC,CAAC,KAAgB,CAAC;IACjE,KAAK,EAAE,GAAG,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;IACrB,OAAO,GAAG,IAAI,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;AAC9C,CAAC;AAOD,MAAM,0BAA0B,GAAG,EAAE,CAAC;AAEtC;;;;;;GAMG;AACH,MAAM,CAAC,KAAK,UAAU,aAAa,CACjC,GAAW,EACX,OAE+D,EAC/D,OAA2B;IAE3B,MAAM,WAAW,EAAE,CAAC;IACpB,MAAM,MAAM,GAAG,SAAS,EAAE,CAAC;IAC3B,MAAM,KAAK,GAAG,aAAa,EAAE,CAAC;IAC9B,KAAK,IAAI,OAAO,GAAG,CAAC,EAAE,OAAO,GAAG,0BAA0B,EAAE,OAAO,IAAI,CAAC,EAAE,CAAC;QACzE,oEAAoE;QACpE,uEAAuE;QACvE,MAAM,QAAQ,GAAG,MAAM,MAAM,CAAC,OAAO,CAAC;YACpC,GAAG,EAAE,qBAAqB,KAAK,gBAAgB;YAC/C,IAAI,EAAE,CAAC,GAAG,CAAC;SACZ,CAAC,CAAC;QACH,MAAM,GAAG,GACP,QAAQ,CAAC,IAAI,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAE,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,KAAgB,CAAC;QAC1E,MAAM,OAAO,GAAG,GAAG,IAAI,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QACrD,MAAM,IAAI,GAAG,MAAM,OAAO,CAAC,OAAO,CAAC,CAAC;QACpC,MAAM,OAAO,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;QACrC,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QAC7B,MAAM,MAAM,GACV,GAAG,IAAI,IAAI;YACT,CAAC,CAAC,MAAM,MAAM,CAAC,OAAO,CAAC;gBACnB,GAAG,EAAE,UAAU,EAAE;oBACf,CAAC,CAAC,eAAe,KAAK,yEAAyE;oBAC/F,CAAC,CAAC,yBAAyB,KAAK,4CAA4C;gBAC9E,IAAI,EAAE,CAAC,GAAG,EAAE,OAAO,EAAE,SAAS,CAAC;aAChC,CAAC;YACJ,CAAC,CAAC,MAAM,MAAM,CAAC,OAAO,CAAC;gBACnB,GAAG,EAAE,UAAU,KAAK,4DAA4D;gBAChF,IAAI,EAAE,CAAC,OAAO,EAAE,SAAS,EAAE,GAAG,EAAE,GAAG,CAAC;aACrC,CAAC,CAAC;QACT,IAAI,MAAM,CAAC,YAAY,KAAK,CAAC;YAAE,SAAS;QACxC,oBAAoB,EAAE,EAAE,GAAG,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;QAC1C,eAAe,EAAE,CAAC,IAAI,CAAC,UAAU,EAAE;YACjC,MAAM,EAAE,UAAU;YAClB,IAAI,EAAE,QAAQ;YACd,GAAG;YACH,GAAG,CAAC,OAAO,EAAE,aAAa,IAAI,EAAE,aAAa,EAAE,OAAO,CAAC,aAAa,EAAE,CAAC;SACxE,CAAC,CAAC;QACH,OAAO,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;IAC7B,CAAC;IACD,MAAM,IAAI,KAAK,CAAC,WAAW,GAAG,8CAA8C,CAAC,CAAC;AAChF,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,UAAU,CAC9B,GAAW,EACX,KAA8B,EAC9B,OAA2B;IAE3B,MAAM,WAAW,EAAE,CAAC;IACpB,MAAM,MAAM,GAAG,SAAS,EAAE,CAAC;IAC3B,MAAM,KAAK,GAAG,aAAa,EAAE,CAAC;IAC9B,MAAM,MAAM,CAAC,OAAO,CAAC;QACnB,GAAG,EAAE,UAAU,EAAE;YACf,CAAC,CAAC,eAAe,KAAK,iIAAiI;YACvJ,CAAC,CAAC,0BAA0B,KAAK,4CAA4C;QAC/E,IAAI,EAAE,CAAC,GAAG,EAAE,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,EAAE,IAAI,CAAC,GAAG,EAAE,CAAC;KAC/C,CAAC,CAAC;IACH,oBAAoB,EAAE,EAAE,GAAG,CAAC,GAAG,EAAE,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC;IACxD,eAAe,EAAE,CAAC,IAAI,CAAC,UAAU,EAAE;QACjC,MAAM,EAAE,UAAU;QAClB,IAAI,EAAE,QAAQ;QACd,GAAG;QACH,GAAG,CAAC,OAAO,EAAE,aAAa,IAAI,EAAE,aAAa,EAAE,OAAO,CAAC,aAAa,EAAE,CAAC;KACxE,CAAC,CAAC;AACL,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,aAAa,CACjC,GAAW,EACX,OAA2B;IAE3B,MAAM,WAAW,EAAE,CAAC;IACpB,MAAM,MAAM,GAAG,SAAS,EAAE,CAAC;IAC3B,MAAM,KAAK,GAAG,aAAa,EAAE,CAAC;IAC9B,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,OAAO,CAAC;QAClC,GAAG,EAAE,eAAe,KAAK,gBAAgB;QACzC,IAAI,EAAE,CAAC,GAAG,CAAC;KACZ,CAAC,CAAC;IACH,oBAAoB,EAAE,EAAE,GAAG,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;IACvC,IAAI,MAAM,CAAC,YAAY,GAAG,CAAC,EAAE,CAAC;QAC5B,eAAe,EAAE,CAAC,IAAI,CAAC,UAAU,EAAE;YACjC,MAAM,EAAE,UAAU;YAClB,IAAI,EAAE,QAAQ;YACd,GAAG;YACH,GAAG,CAAC,OAAO,EAAE,aAAa,IAAI,EAAE,aAAa,EAAE,OAAO,CAAC,aAAa,EAAE,CAAC;SACxE,CAAC,CAAC;QACH,OAAO,IAAI,CAAC;IACd,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,cAAc;IAGlC,MAAM,WAAW,EAAE,CAAC;IACpB,MAAM,MAAM,GAAG,SAAS,EAAE,CAAC;IAC3B,MAAM,KAAK,GAAG,aAAa,EAAE,CAAC;IAC9B,MAAM,EAAE,IAAI,EAAE,GAAG,MAAM,MAAM,CAAC,OAAO,CAAC,0BAA0B,KAAK,EAAE,CAAC,CAAC;IACzE,MAAM,MAAM,GAA4C,EAAE,CAAC;IAC3D,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;QACvB,MAAM,CAAC,GAAG,CAAC,GAAa,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,KAAe,CAAC,CAAC;IAC9D,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC","sourcesContent":["import type { EventEmitter } from \"node:events\";\n\nimport { getDbExec, isPostgres, intType } from \"../db/client.js\";\nimport { ensureIndexExists, ensureTableExists } from \"../db/ddl-guard.js\";\nimport { widenIntColumnsToBigInt } from \"../db/widen-columns.js\";\nimport { getRequestContext } from \"../server/request-context.js\";\nimport { createEventEmitter } from \"../shared/optional-node-builtins.js\";\n\nlet _initPromise: Promise<void> | undefined;\n\n// Per-request memoization of settings reads, keyed on the active\n// AsyncLocalStorage RequestContext (WeakMap → freed with the request). One\n// action request can read the same setting several times (org resolution,\n// guards, the action body), and each read is a network round trip on\n// serverless Postgres. Mirrors the per-request session/org caches on\n// event.context. The cache holds the raw JSON string and re-parses per hit\n// so callers can't mutate a shared object; writes in the same request are\n// written through, while other in-flight requests keep their snapshot for\n// their own (short) lifetime.\nconst _requestSettingsCache = new WeakMap<object, Map<string, string | null>>();\n\nfunction requestSettingsCache(): Map<string, string | null> | null {\n const ctx = getRequestContext();\n if (!ctx || typeof ctx !== \"object\") return null;\n let cache = _requestSettingsCache.get(ctx);\n if (!cache) {\n cache = new Map();\n _requestSettingsCache.set(ctx, cache);\n }\n return cache;\n}\n\n// Created lazily so this module can be evaluated in the browser dev graph\n// without a top-level `new EventEmitter()` tripping Vite's externalized\n// `node:events` stub. The emitter drives server-side SSE fan-out only.\nlet _emitter: EventEmitter | undefined;\n\nfunction settingsEmitter(): EventEmitter {\n if (!_emitter) _emitter = createEventEmitter();\n return _emitter;\n}\n\nexport function getSettingsEmitter(): EventEmitter {\n return settingsEmitter();\n}\n\nfunction settingsTable(): string {\n return isPostgres() ? \"public.settings\" : \"settings\";\n}\n\nasync function ensureTable(): Promise<void> {\n if (!_initPromise) {\n _initPromise = (async () => {\n const client = getDbExec();\n const table = settingsTable();\n const createSql = `\n CREATE TABLE IF NOT EXISTS ${table} (\n key TEXT PRIMARY KEY,\n value TEXT NOT NULL,\n updated_at ${intType()} NOT NULL\n )\n `;\n\n if (isPostgres()) {\n // Hot path: the `settings` table and its poll index are virtually\n // always already present in production. Issuing `CREATE TABLE`/\n // `CREATE INDEX` still takes a lock that, in a fresh background-worker\n // process behind a concurrent connection on the shared Neon DB, can\n // block ~indefinitely (ACCESS EXCLUSIVE for CREATE TABLE; a write-\n // blocking SHARE lock for CREATE INDEX). `ensureTableExists` /\n // `ensureIndexExists` probe `information_schema`/`pg_indexes` first\n // (plain reads, no lock) and run DDL ONLY for what is actually missing,\n // bounding any DDL with a transaction-scoped `lock_timeout`. They also\n // re-probe after a swallowed lock-timeout and THROW if the schema is\n // still missing, so a timed-out DDL never poisons this init memo with\n // missing schema. `settingsTable()` is `public.settings` on Postgres;\n // the existence checks use the unqualified table name.\n await ensureTableExists(\"settings\", createSql);\n // Older deployments (pre BIGINT-compat) have a 32-bit `updated_at`; on\n // Postgres the `Date.now()` written on every setSetting overflows int4.\n // widenIntColumnsToBigInt already probes information_schema and only\n // ALTERs columns that are still int4 — a no-op on fresh/widened DBs.\n await widenIntColumnsToBigInt(\"settings\", [\"updated_at\"]);\n // Index for the poll watermark query: `SELECT MAX(updated_at)`.\n await ensureIndexExists(\n \"settings_updated_at_idx\",\n `CREATE INDEX IF NOT EXISTS settings_updated_at_idx ON ${table} (updated_at)`,\n );\n return;\n }\n\n // SQLite (local dev): no lock problem — keep the original behaviour.\n await client.execute(createSql);\n // No-op on SQLite (INTEGER is already 64-bit).\n await widenIntColumnsToBigInt(\"settings\", [\"updated_at\"]);\n // Index for the poll watermark query: `SELECT MAX(updated_at) FROM settings`.\n // MAX on an indexed column avoids a full-table scan on every poll cycle.\n // IF NOT EXISTS makes it idempotent on existing databases.\n try {\n await client.execute(\n `CREATE INDEX IF NOT EXISTS settings_updated_at_idx ON ${table} (updated_at)`,\n );\n } catch {\n // Index already exists or the dialect rejected a duplicate.\n }\n })().catch((err) => {\n // Retry init on the next call after a failed startup.\n _initPromise = undefined;\n throw err;\n });\n }\n return _initPromise;\n}\n\nexport async function getSetting(\n key: string,\n): Promise<Record<string, unknown> | null> {\n const cache = requestSettingsCache();\n if (cache?.has(key)) {\n const cached = cache.get(key);\n return cached == null ? null : JSON.parse(cached);\n }\n await ensureTable();\n const client = getDbExec();\n const table = settingsTable();\n const { rows } = await client.execute({\n sql: `SELECT value FROM ${table} WHERE key = ?`,\n args: [key],\n });\n const raw = rows.length === 0 ? null : (rows[0].value as string);\n cache?.set(key, raw);\n return raw == null ? null : JSON.parse(raw);\n}\n\nexport interface StoreWriteOptions {\n /** Tag identifying who initiated this write (e.g. a tab ID). */\n requestSource?: string;\n}\n\nconst SETTINGS_MUTATION_ATTEMPTS = 25;\n\n/**\n * Atomically derive and persist one setting with an optimistic raw-value CAS.\n * This works across SQLite/libSQL and Postgres and remains safe across\n * horizontally scaled processes where an in-memory mutex would not.\n * The updater may run more than once after contention and must not perform\n * external side effects.\n */\nexport async function mutateSetting(\n key: string,\n updater: (\n current: Record<string, unknown> | null,\n ) => Record<string, unknown> | Promise<Record<string, unknown>>,\n options?: StoreWriteOptions,\n): Promise<Record<string, unknown>> {\n await ensureTable();\n const client = getDbExec();\n const table = settingsTable();\n for (let attempt = 0; attempt < SETTINGS_MUTATION_ATTEMPTS; attempt += 1) {\n // Deliberately bypass the request cache: a failed CAS means another\n // request committed a newer value and the next attempt must reread it.\n const snapshot = await client.execute({\n sql: `SELECT value FROM ${table} WHERE key = ?`,\n args: [key],\n });\n const raw =\n snapshot.rows.length === 0 ? null : (snapshot.rows[0]?.value as string);\n const current = raw == null ? null : JSON.parse(raw);\n const next = await updater(current);\n const nextRaw = JSON.stringify(next);\n const timestamp = Date.now();\n const result =\n raw == null\n ? await client.execute({\n sql: isPostgres()\n ? `INSERT INTO ${table} (key, value, updated_at) VALUES (?, ?, ?) ON CONFLICT (key) DO NOTHING`\n : `INSERT OR IGNORE INTO ${table} (key, value, updated_at) VALUES (?, ?, ?)`,\n args: [key, nextRaw, timestamp],\n })\n : await client.execute({\n sql: `UPDATE ${table} SET value = ?, updated_at = ? WHERE key = ? AND value = ?`,\n args: [nextRaw, timestamp, key, raw],\n });\n if (result.rowsAffected === 0) continue;\n requestSettingsCache()?.set(key, nextRaw);\n settingsEmitter().emit(\"settings\", {\n source: \"settings\",\n type: \"change\",\n key,\n ...(options?.requestSource && { requestSource: options.requestSource }),\n });\n return JSON.parse(nextRaw);\n }\n throw new Error(`Setting ${key} changed too many times; retry the mutation.`);\n}\n\nexport async function putSetting(\n key: string,\n value: Record<string, unknown>,\n options?: StoreWriteOptions,\n): Promise<void> {\n await ensureTable();\n const client = getDbExec();\n const table = settingsTable();\n await client.execute({\n sql: isPostgres()\n ? `INSERT INTO ${table} (key, value, updated_at) VALUES (?, ?, ?) ON CONFLICT (key) DO UPDATE SET value=EXCLUDED.value, updated_at=EXCLUDED.updated_at`\n : `INSERT OR REPLACE INTO ${table} (key, value, updated_at) VALUES (?, ?, ?)`,\n args: [key, JSON.stringify(value), Date.now()],\n });\n requestSettingsCache()?.set(key, JSON.stringify(value));\n settingsEmitter().emit(\"settings\", {\n source: \"settings\",\n type: \"change\",\n key,\n ...(options?.requestSource && { requestSource: options.requestSource }),\n });\n}\n\nexport async function deleteSetting(\n key: string,\n options?: StoreWriteOptions,\n): Promise<boolean> {\n await ensureTable();\n const client = getDbExec();\n const table = settingsTable();\n const result = await client.execute({\n sql: `DELETE FROM ${table} WHERE key = ?`,\n args: [key],\n });\n requestSettingsCache()?.set(key, null);\n if (result.rowsAffected > 0) {\n settingsEmitter().emit(\"settings\", {\n source: \"settings\",\n type: \"delete\",\n key,\n ...(options?.requestSource && { requestSource: options.requestSource }),\n });\n return true;\n }\n return false;\n}\n\nexport async function getAllSettings(): Promise<\n Record<string, Record<string, unknown>>\n> {\n await ensureTable();\n const client = getDbExec();\n const table = settingsTable();\n const { rows } = await client.execute(`SELECT key, value FROM ${table}`);\n const result: Record<string, Record<string, unknown>> = {};\n for (const row of rows) {\n result[row.key as string] = JSON.parse(row.value as string);\n }\n return result;\n}\n"]}
@@ -0,0 +1,23 @@
1
+ /**
2
+ * Browser-safe accessors for optional Node builtins.
3
+ *
4
+ * `node:async_hooks` and `node:events` are server-only, but the modules that
5
+ * use them (db telemetry, settings/resource emitters) can land in the browser
6
+ * dev graph before tree-shaking runs. A static `import { X } from "node:..."`
7
+ * resolves to Vite's externalized stub and throws the instant the value is
8
+ * touched at module load. We read the builtin through `process.getBuiltinModule`
9
+ * instead — the same guard `server/request-context.ts` uses — so there is no
10
+ * static `node:` import to evaluate in the browser, and callers fall back to a
11
+ * no-op on non-Node runtimes (browser, or Node without getBuiltinModule).
12
+ */
13
+ import type { AsyncLocalStorage } from "node:async_hooks";
14
+ import type { EventEmitter } from "node:events";
15
+ export type AsyncLocalStorageCtor = new <T>() => AsyncLocalStorage<T>;
16
+ export declare function getAsyncLocalStorageCtor(): AsyncLocalStorageCtor | undefined;
17
+ /**
18
+ * Returns a real Node EventEmitter on Node, or a no-op emitter elsewhere. The
19
+ * emitters that use this drive server-side SSE fan-out; nothing subscribes in
20
+ * the browser, so the no-op fallback is inert rather than wrong.
21
+ */
22
+ export declare function createEventEmitter(): EventEmitter;
23
+ //# sourceMappingURL=optional-node-builtins.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"optional-node-builtins.d.ts","sourceRoot":"","sources":["../../src/shared/optional-node-builtins.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AACH,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAC1D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAqBhD,MAAM,MAAM,qBAAqB,GAAG,KAAK,CAAC,OAAO,iBAAiB,CAAC,CAAC,CAAC,CAAC;AAEtE,wBAAgB,wBAAwB,IAAI,qBAAqB,GAAG,SAAS,CAI5E;AAID;;;;GAIG;AACH,wBAAgB,kBAAkB,IAAI,YAAY,CAgBjD"}
@@ -0,0 +1,35 @@
1
+ function nodeBuiltin(name) {
2
+ const proc = typeof process === "undefined" ? undefined : process;
3
+ if (typeof window !== "undefined" ||
4
+ !proc ||
5
+ !proc.versions?.node ||
6
+ typeof proc.getBuiltinModule !== "function") {
7
+ return undefined;
8
+ }
9
+ return proc.getBuiltinModule(name);
10
+ }
11
+ export function getAsyncLocalStorageCtor() {
12
+ return nodeBuiltin("node:async_hooks")?.AsyncLocalStorage;
13
+ }
14
+ /**
15
+ * Returns a real Node EventEmitter on Node, or a no-op emitter elsewhere. The
16
+ * emitters that use this drive server-side SSE fan-out; nothing subscribes in
17
+ * the browser, so the no-op fallback is inert rather than wrong.
18
+ */
19
+ export function createEventEmitter() {
20
+ const Ctor = nodeBuiltin("node:events")?.EventEmitter;
21
+ if (Ctor)
22
+ return new Ctor();
23
+ const noop = {
24
+ on: () => noop,
25
+ off: () => noop,
26
+ once: () => noop,
27
+ addListener: () => noop,
28
+ removeListener: () => noop,
29
+ removeAllListeners: () => noop,
30
+ setMaxListeners: () => noop,
31
+ emit: () => false,
32
+ };
33
+ return noop;
34
+ }
35
+ //# sourceMappingURL=optional-node-builtins.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"optional-node-builtins.js","sourceRoot":"","sources":["../../src/shared/optional-node-builtins.ts"],"names":[],"mappings":"AAoBA,SAAS,WAAW,CAAI,IAAY;IAClC,MAAM,IAAI,GACR,OAAO,OAAO,KAAK,WAAW,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAE,OAA0B,CAAC;IAC3E,IACE,OAAO,MAAM,KAAK,WAAW;QAC7B,CAAC,IAAI;QACL,CAAC,IAAI,CAAC,QAAQ,EAAE,IAAI;QACpB,OAAO,IAAI,CAAC,gBAAgB,KAAK,UAAU,EAC3C,CAAC;QACD,OAAO,SAAS,CAAC;IACnB,CAAC;IACD,OAAO,IAAI,CAAC,gBAAgB,CAAC,IAAI,CAAkB,CAAC;AACtD,CAAC;AAID,MAAM,UAAU,wBAAwB;IACtC,OAAO,WAAW,CAChB,kBAAkB,CACnB,EAAE,iBAAiB,CAAC;AACvB,CAAC;AAID;;;;GAIG;AACH,MAAM,UAAU,kBAAkB;IAChC,MAAM,IAAI,GAAG,WAAW,CACtB,aAAa,CACd,EAAE,YAAY,CAAC;IAChB,IAAI,IAAI;QAAE,OAAO,IAAI,IAAI,EAAE,CAAC;IAC5B,MAAM,IAAI,GAAG;QACX,EAAE,EAAE,GAAG,EAAE,CAAC,IAAI;QACd,GAAG,EAAE,GAAG,EAAE,CAAC,IAAI;QACf,IAAI,EAAE,GAAG,EAAE,CAAC,IAAI;QAChB,WAAW,EAAE,GAAG,EAAE,CAAC,IAAI;QACvB,cAAc,EAAE,GAAG,EAAE,CAAC,IAAI;QAC1B,kBAAkB,EAAE,GAAG,EAAE,CAAC,IAAI;QAC9B,eAAe,EAAE,GAAG,EAAE,CAAC,IAAI;QAC3B,IAAI,EAAE,GAAG,EAAE,CAAC,KAAK;KAClB,CAAC;IACF,OAAO,IAA+B,CAAC;AACzC,CAAC","sourcesContent":["/**\n * Browser-safe accessors for optional Node builtins.\n *\n * `node:async_hooks` and `node:events` are server-only, but the modules that\n * use them (db telemetry, settings/resource emitters) can land in the browser\n * dev graph before tree-shaking runs. A static `import { X } from \"node:...\"`\n * resolves to Vite's externalized stub and throws the instant the value is\n * touched at module load. We read the builtin through `process.getBuiltinModule`\n * instead — the same guard `server/request-context.ts` uses — so there is no\n * static `node:` import to evaluate in the browser, and callers fall back to a\n * no-op on non-Node runtimes (browser, or Node without getBuiltinModule).\n */\nimport type { AsyncLocalStorage } from \"node:async_hooks\";\nimport type { EventEmitter } from \"node:events\";\n\ntype BuiltinProcess = {\n versions?: { node?: string };\n getBuiltinModule?: (name: string) => unknown;\n};\n\nfunction nodeBuiltin<T>(name: string): T | undefined {\n const proc =\n typeof process === \"undefined\" ? undefined : (process as BuiltinProcess);\n if (\n typeof window !== \"undefined\" ||\n !proc ||\n !proc.versions?.node ||\n typeof proc.getBuiltinModule !== \"function\"\n ) {\n return undefined;\n }\n return proc.getBuiltinModule(name) as T | undefined;\n}\n\nexport type AsyncLocalStorageCtor = new <T>() => AsyncLocalStorage<T>;\n\nexport function getAsyncLocalStorageCtor(): AsyncLocalStorageCtor | undefined {\n return nodeBuiltin<{ AsyncLocalStorage: AsyncLocalStorageCtor }>(\n \"node:async_hooks\",\n )?.AsyncLocalStorage;\n}\n\ntype EventEmitterCtor = new () => EventEmitter;\n\n/**\n * Returns a real Node EventEmitter on Node, or a no-op emitter elsewhere. The\n * emitters that use this drive server-side SSE fan-out; nothing subscribes in\n * the browser, so the no-op fallback is inert rather than wrong.\n */\nexport function createEventEmitter(): EventEmitter {\n const Ctor = nodeBuiltin<{ EventEmitter: EventEmitterCtor }>(\n \"node:events\",\n )?.EventEmitter;\n if (Ctor) return new Ctor();\n const noop = {\n on: () => noop,\n off: () => noop,\n once: () => noop,\n addListener: () => noop,\n removeListener: () => noop,\n removeAllListeners: () => noop,\n setMaxListeners: () => noop,\n emit: () => false,\n };\n return noop as unknown as EventEmitter;\n}\n"]}
@@ -37,7 +37,7 @@ Keep definitions in a shared TypeScript module so server and client code use the
37
37
  same stable key. Flags are boolean and default-off.
38
38
 
39
39
  ```ts
40
- import { defineFeatureFlag } from "@agent-native/core/feature-flags";
40
+ import { defineFeatureFlag } from "@agent-native/core/feature-flags/registry";
41
41
 
42
42
  export const FULL_APP_BUILDING = defineFeatureFlag({
43
43
  key: "full-app-building",
@@ -37,7 +37,7 @@ Keep definitions in a shared TypeScript module so server and client code use the
37
37
  same stable key. Flags are boolean and default-off.
38
38
 
39
39
  ```ts
40
- import { defineFeatureFlag } from "@agent-native/core/feature-flags";
40
+ import { defineFeatureFlag } from "@agent-native/core/feature-flags/registry";
41
41
 
42
42
  export const FULL_APP_BUILDING = defineFeatureFlag({
43
43
  key: "full-app-building",
@@ -37,7 +37,7 @@ Keep definitions in a shared TypeScript module so server and client code use the
37
37
  same stable key. Flags are boolean and default-off.
38
38
 
39
39
  ```ts
40
- import { defineFeatureFlag } from "@agent-native/core/feature-flags";
40
+ import { defineFeatureFlag } from "@agent-native/core/feature-flags/registry";
41
41
 
42
42
  export const FULL_APP_BUILDING = defineFeatureFlag({
43
43
  key: "full-app-building",
@@ -37,7 +37,7 @@ Keep definitions in a shared TypeScript module so server and client code use the
37
37
  same stable key. Flags are boolean and default-off.
38
38
 
39
39
  ```ts
40
- import { defineFeatureFlag } from "@agent-native/core/feature-flags";
40
+ import { defineFeatureFlag } from "@agent-native/core/feature-flags/registry";
41
41
 
42
42
  export const FULL_APP_BUILDING = defineFeatureFlag({
43
43
  key: "full-app-building",
@@ -1 +1 @@
1
- {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/vite/client.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/vite/client.ts"],"names":[],"mappings":"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"}
@@ -683,6 +683,7 @@ const CORE_CLIENT_SUBPATHS = [
683
683
  "@agent-native/core/client/components/RemoteSelectionRings",
684
684
  "@agent-native/core/client/visual-style-controls",
685
685
  "@agent-native/core/client/feature-flags",
686
+ "@agent-native/core/feature-flags/registry",
686
687
  "@agent-native/core/client/hooks",
687
688
  "@agent-native/core/client/host",
688
689
  "@agent-native/core/client/i18n",
@@ -951,6 +952,7 @@ function getCoreSourceAliases(cwd) {
951
952
  "@agent-native/core/client/components/RemoteSelectionRings": path.join(coreSrc, "client/tombstone/remote-selection-rings.ts"),
952
953
  "@agent-native/core/client/visual-style-controls": path.join(coreSrc, "client/tombstone/visual-style-controls.ts"),
953
954
  "@agent-native/core/client/feature-flags": path.join(coreSrc, "client/feature-flags/index.ts"),
955
+ "@agent-native/core/feature-flags/registry": path.join(coreSrc, "feature-flags/registry.ts"),
954
956
  "@agent-native/core/client/hooks": path.join(coreSrc, "client/hooks/index.ts"),
955
957
  "@agent-native/core/client/host": path.join(coreSrc, "client/host/index.ts"),
956
958
  "@agent-native/core/client/i18n": path.join(coreSrc, "client/i18n.tsx"),