@immediately-run/sdk 0.10.0 → 0.12.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/boot.cjs +12 -1
- package/dist/boot.cjs.map +1 -1
- package/dist/boot.js +14 -3
- package/dist/boot.js.map +1 -1
- package/dist/diagnostics.cjs +51 -0
- package/dist/diagnostics.cjs.map +1 -0
- package/dist/diagnostics.d.cts +43 -0
- package/dist/diagnostics.d.ts +43 -0
- package/dist/diagnostics.js +25 -0
- package/dist/diagnostics.js.map +1 -0
- package/dist/dnd.cjs +56 -0
- package/dist/dnd.cjs.map +1 -0
- package/dist/dnd.d.cts +50 -0
- package/dist/dnd.d.ts +50 -0
- package/dist/dnd.js +29 -0
- package/dist/dnd.js.map +1 -0
- package/dist/hostRuntime.cjs.map +1 -1
- package/dist/hostRuntime.d.cts +5 -0
- package/dist/hostRuntime.d.ts +5 -0
- package/dist/hostRuntime.js.map +1 -1
- package/dist/index.cjs +6 -0
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +3 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.js +3 -0
- package/dist/index.js.map +1 -1
- package/dist/markers.cjs +59 -0
- package/dist/markers.cjs.map +1 -0
- package/dist/markers.d.cts +21 -0
- package/dist/markers.d.ts +21 -0
- package/dist/markers.js +32 -0
- package/dist/markers.js.map +1 -0
- package/dist/region.cjs +47 -0
- package/dist/region.cjs.map +1 -0
- package/dist/region.d.cts +14 -0
- package/dist/region.d.ts +14 -0
- package/dist/region.js +22 -0
- package/dist/region.js.map +1 -0
- package/dist/testing.cjs +74 -0
- package/dist/testing.cjs.map +1 -0
- package/dist/testing.d.cts +53 -0
- package/dist/testing.d.ts +53 -0
- package/dist/testing.js +50 -0
- package/dist/testing.js.map +1 -0
- package/dist/version.cjs +1 -1
- package/dist/version.cjs.map +1 -1
- package/dist/version.d.cts +1 -1
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/dist/version.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -26,12 +26,15 @@ __reExport(index_exports, require("./theme"), module.exports);
|
|
|
26
26
|
__reExport(index_exports, require("./editorContext"), module.exports);
|
|
27
27
|
__reExport(index_exports, require("./editor"), module.exports);
|
|
28
28
|
__reExport(index_exports, require("./formFactor"), module.exports);
|
|
29
|
+
__reExport(index_exports, require("./region"), module.exports);
|
|
29
30
|
__reExport(index_exports, require("./mounts"), module.exports);
|
|
30
31
|
__reExport(index_exports, require("./contribute"), module.exports);
|
|
31
32
|
__reExport(index_exports, require("./catalog"), module.exports);
|
|
32
33
|
__reExport(index_exports, require("./ipc"), module.exports);
|
|
34
|
+
__reExport(index_exports, require("./dnd"), module.exports);
|
|
33
35
|
__reExport(index_exports, require("./netFetch"), module.exports);
|
|
34
36
|
__reExport(index_exports, require("./secrets"), module.exports);
|
|
37
|
+
__reExport(index_exports, require("./diagnostics"), module.exports);
|
|
35
38
|
__reExport(index_exports, require("./tasks"), module.exports);
|
|
36
39
|
__reExport(index_exports, require("./runtime"), module.exports);
|
|
37
40
|
__reExport(index_exports, require("./irMarkers"), module.exports);
|
|
@@ -51,12 +54,15 @@ __reExport(index_exports, require("./sandboxTypes"), module.exports);
|
|
|
51
54
|
...require("./editorContext"),
|
|
52
55
|
...require("./editor"),
|
|
53
56
|
...require("./formFactor"),
|
|
57
|
+
...require("./region"),
|
|
54
58
|
...require("./mounts"),
|
|
55
59
|
...require("./contribute"),
|
|
56
60
|
...require("./catalog"),
|
|
57
61
|
...require("./ipc"),
|
|
62
|
+
...require("./dnd"),
|
|
58
63
|
...require("./netFetch"),
|
|
59
64
|
...require("./secrets"),
|
|
65
|
+
...require("./diagnostics"),
|
|
60
66
|
...require("./tasks"),
|
|
61
67
|
...require("./runtime"),
|
|
62
68
|
...require("./irMarkers"),
|
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["export * from \"./MDXProvider\";\nexport * from \"./routing\";\nexport * from \"./boot\";\nexport * from './components/Include';\nexport * from './components/MDXComponents';\nexport * from './hooks'\nexport * from './auth';\nexport * from './theme';\nexport * from './editorContext';\nexport * from './editor';\nexport * from './formFactor';\nexport * from './mounts';\nexport * from './contribute';\nexport * from './catalog';\nexport * from './ipc';\nexport * from './netFetch';\nexport * from './secrets';\nexport * from './tasks';\nexport * from './runtime';\nexport * from './irMarkers';\nexport * from './ready';\nexport * from './protocolStream';\nexport * from './sandboxTypes';\n"],"mappings":";;;;;;;;;;;;;;;AAAA;AAAA;AAAA,0BAAc,0BAAd;AACA,0BAAc,sBADd;AAEA,0BAAc,mBAFd;AAGA,0BAAc,iCAHd;AAIA,0BAAc,uCAJd;AAKA,0BAAc,oBALd;AAMA,0BAAc,mBANd;AAOA,0BAAc,oBAPd;AAQA,0BAAc,4BARd;AASA,0BAAc,qBATd;AAUA,0BAAc,yBAVd;AAWA,0BAAc,qBAXd;AAYA,0BAAc,
|
|
1
|
+
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["export * from \"./MDXProvider\";\nexport * from \"./routing\";\nexport * from \"./boot\";\nexport * from './components/Include';\nexport * from './components/MDXComponents';\nexport * from './hooks'\nexport * from './auth';\nexport * from './theme';\nexport * from './editorContext';\nexport * from './editor';\nexport * from './formFactor';\nexport * from './region';\nexport * from './mounts';\nexport * from './contribute';\nexport * from './catalog';\nexport * from './ipc';\nexport * from './dnd';\nexport * from './netFetch';\nexport * from './secrets';\nexport * from './diagnostics';\nexport * from './tasks';\nexport * from './runtime';\nexport * from './irMarkers';\nexport * from './ready';\nexport * from './protocolStream';\nexport * from './sandboxTypes';\n"],"mappings":";;;;;;;;;;;;;;;AAAA;AAAA;AAAA,0BAAc,0BAAd;AACA,0BAAc,sBADd;AAEA,0BAAc,mBAFd;AAGA,0BAAc,iCAHd;AAIA,0BAAc,uCAJd;AAKA,0BAAc,oBALd;AAMA,0BAAc,mBANd;AAOA,0BAAc,oBAPd;AAQA,0BAAc,4BARd;AASA,0BAAc,qBATd;AAUA,0BAAc,yBAVd;AAWA,0BAAc,qBAXd;AAYA,0BAAc,qBAZd;AAaA,0BAAc,yBAbd;AAcA,0BAAc,sBAdd;AAeA,0BAAc,kBAfd;AAgBA,0BAAc,kBAhBd;AAiBA,0BAAc,uBAjBd;AAkBA,0BAAc,sBAlBd;AAmBA,0BAAc,0BAnBd;AAoBA,0BAAc,oBApBd;AAqBA,0BAAc,sBArBd;AAsBA,0BAAc,wBAtBd;AAuBA,0BAAc,oBAvBd;AAwBA,0BAAc,6BAxBd;AAyBA,0BAAc,2BAzBd;","names":[]}
|
package/dist/index.d.cts
CHANGED
|
@@ -9,12 +9,15 @@ export { HostTheme, getHostTheme, onHostThemeChange, setHostTheme, useHostTheme
|
|
|
9
9
|
export { EditorContext, getEditorContext, onEditorContextChange, useEditorContext } from './editorContext.cjs';
|
|
10
10
|
export { EditTarget, EditorOpenError, EditorSessionError, EditorWriteError, RequestEditError, closeFile, createFile, createFolder, deleteEntry, openInEditor, renameEntry, requestEdit, setActiveFile, uploadFile } from './editor.cjs';
|
|
11
11
|
export { FormFactor, FormFactorClass, Orientation, getFormFactor, onFormFactorChange, useFormFactor } from './formFactor.cjs';
|
|
12
|
+
export { getRegion, useRegion } from './region.cjs';
|
|
12
13
|
export { GrantRecord, Member, MountQuery, MountRemoveReason, MountRule, RemovedMount, ResolvedUser, Role, SandboxMount, SpaceError, SpaceInfo, createSpace, findMount, getAppMountPath, getMounts, getSpaceMembers, importSettingsFromParent, listAllSpaces, listGrants, listSettingsApps, listSpaces, lookupUser, makeContentRef, mount, mountSpace, onMountsChange, openSettings, openSettingsOf, requestMount, requestSpace, resolveContentRef, resolveContentRefs, revokeGrant, setSpaceRole, shareSpace, unmountSpace, unshareSpace, useMounts, waitForMount } from './mounts.cjs';
|
|
13
14
|
export { ContributeMode, ContributeOptions, ContributionEvent, ContributionResult, contribute } from './contribute.cjs';
|
|
14
15
|
export { ApiMethod, getCatalog, invoke, invokeStream, onCatalogChange, useCatalog } from './catalog.cjs';
|
|
15
16
|
export { RegionMessage, onRegionMessage, postToRegion, useRegionMessage } from './ipc.cjs';
|
|
17
|
+
export { DraggableItem, DroppedItem, ItemDragError, cancelItemDrag, onItemDrop, startItemDrag, useDroppedItem } from './dnd.cjs';
|
|
16
18
|
export { HostFetchInit, HostFetchResponse, HostFetchStreamEvent, HostFetchStreamResult, hostFetch, hostFetchStream } from './netFetch.cjs';
|
|
17
19
|
export { SecretError, SecretGrant, SecretHints, SecretQuery, SecretType, SecretView, getSecrets, onSecretsChange, requestAddSecret, requestSecret, revokeSecret, useSecrets } from './secrets.cjs';
|
|
20
|
+
export { BuildError, ConsoleEntry, ConsoleLevel, Diagnostics, DiagnosticsProvenance, getDiagnostics, onDiagnosticsChange, useDiagnostics } from './diagnostics.cjs';
|
|
18
21
|
export { DirCap, FileCap, TaskInput, cancelTask, capDir, capFile, completeTask, getTaskInput, invokeTask, useTaskInput } from './tasks.cjs';
|
|
19
22
|
export { SDK_PROTOCOL_VERSION, SdkHandshake, announceHandshake, sdkHandshake } from './runtime.cjs';
|
|
20
23
|
export { ForwardedMarker, IR_MARKERS, IrMarkerName, isAllowedMarkerName, isIrMarkerName, resolveInteractive, validateMarker } from './irMarkers.cjs';
|
package/dist/index.d.ts
CHANGED
|
@@ -9,12 +9,15 @@ export { HostTheme, getHostTheme, onHostThemeChange, setHostTheme, useHostTheme
|
|
|
9
9
|
export { EditorContext, getEditorContext, onEditorContextChange, useEditorContext } from './editorContext.js';
|
|
10
10
|
export { EditTarget, EditorOpenError, EditorSessionError, EditorWriteError, RequestEditError, closeFile, createFile, createFolder, deleteEntry, openInEditor, renameEntry, requestEdit, setActiveFile, uploadFile } from './editor.js';
|
|
11
11
|
export { FormFactor, FormFactorClass, Orientation, getFormFactor, onFormFactorChange, useFormFactor } from './formFactor.js';
|
|
12
|
+
export { getRegion, useRegion } from './region.js';
|
|
12
13
|
export { GrantRecord, Member, MountQuery, MountRemoveReason, MountRule, RemovedMount, ResolvedUser, Role, SandboxMount, SpaceError, SpaceInfo, createSpace, findMount, getAppMountPath, getMounts, getSpaceMembers, importSettingsFromParent, listAllSpaces, listGrants, listSettingsApps, listSpaces, lookupUser, makeContentRef, mount, mountSpace, onMountsChange, openSettings, openSettingsOf, requestMount, requestSpace, resolveContentRef, resolveContentRefs, revokeGrant, setSpaceRole, shareSpace, unmountSpace, unshareSpace, useMounts, waitForMount } from './mounts.js';
|
|
13
14
|
export { ContributeMode, ContributeOptions, ContributionEvent, ContributionResult, contribute } from './contribute.js';
|
|
14
15
|
export { ApiMethod, getCatalog, invoke, invokeStream, onCatalogChange, useCatalog } from './catalog.js';
|
|
15
16
|
export { RegionMessage, onRegionMessage, postToRegion, useRegionMessage } from './ipc.js';
|
|
17
|
+
export { DraggableItem, DroppedItem, ItemDragError, cancelItemDrag, onItemDrop, startItemDrag, useDroppedItem } from './dnd.js';
|
|
16
18
|
export { HostFetchInit, HostFetchResponse, HostFetchStreamEvent, HostFetchStreamResult, hostFetch, hostFetchStream } from './netFetch.js';
|
|
17
19
|
export { SecretError, SecretGrant, SecretHints, SecretQuery, SecretType, SecretView, getSecrets, onSecretsChange, requestAddSecret, requestSecret, revokeSecret, useSecrets } from './secrets.js';
|
|
20
|
+
export { BuildError, ConsoleEntry, ConsoleLevel, Diagnostics, DiagnosticsProvenance, getDiagnostics, onDiagnosticsChange, useDiagnostics } from './diagnostics.js';
|
|
18
21
|
export { DirCap, FileCap, TaskInput, cancelTask, capDir, capFile, completeTask, getTaskInput, invokeTask, useTaskInput } from './tasks.js';
|
|
19
22
|
export { SDK_PROTOCOL_VERSION, SdkHandshake, announceHandshake, sdkHandshake } from './runtime.js';
|
|
20
23
|
export { ForwardedMarker, IR_MARKERS, IrMarkerName, isAllowedMarkerName, isIrMarkerName, resolveInteractive, validateMarker } from './irMarkers.js';
|
package/dist/index.js
CHANGED
|
@@ -9,12 +9,15 @@ export * from "./theme";
|
|
|
9
9
|
export * from "./editorContext";
|
|
10
10
|
export * from "./editor";
|
|
11
11
|
export * from "./formFactor";
|
|
12
|
+
export * from "./region";
|
|
12
13
|
export * from "./mounts";
|
|
13
14
|
export * from "./contribute";
|
|
14
15
|
export * from "./catalog";
|
|
15
16
|
export * from "./ipc";
|
|
17
|
+
export * from "./dnd";
|
|
16
18
|
export * from "./netFetch";
|
|
17
19
|
export * from "./secrets";
|
|
20
|
+
export * from "./diagnostics";
|
|
18
21
|
export * from "./tasks";
|
|
19
22
|
export * from "./runtime";
|
|
20
23
|
export * from "./irMarkers";
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["export * from \"./MDXProvider\";\nexport * from \"./routing\";\nexport * from \"./boot\";\nexport * from './components/Include';\nexport * from './components/MDXComponents';\nexport * from './hooks'\nexport * from './auth';\nexport * from './theme';\nexport * from './editorContext';\nexport * from './editor';\nexport * from './formFactor';\nexport * from './mounts';\nexport * from './contribute';\nexport * from './catalog';\nexport * from './ipc';\nexport * from './netFetch';\nexport * from './secrets';\nexport * from './tasks';\nexport * from './runtime';\nexport * from './irMarkers';\nexport * from './ready';\nexport * from './protocolStream';\nexport * from './sandboxTypes';\n"],"mappings":"AAAA,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;","names":[]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["export * from \"./MDXProvider\";\nexport * from \"./routing\";\nexport * from \"./boot\";\nexport * from './components/Include';\nexport * from './components/MDXComponents';\nexport * from './hooks'\nexport * from './auth';\nexport * from './theme';\nexport * from './editorContext';\nexport * from './editor';\nexport * from './formFactor';\nexport * from './region';\nexport * from './mounts';\nexport * from './contribute';\nexport * from './catalog';\nexport * from './ipc';\nexport * from './dnd';\nexport * from './netFetch';\nexport * from './secrets';\nexport * from './diagnostics';\nexport * from './tasks';\nexport * from './runtime';\nexport * from './irMarkers';\nexport * from './ready';\nexport * from './protocolStream';\nexport * from './sandboxTypes';\n"],"mappings":"AAAA,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;","names":[]}
|
package/dist/markers.cjs
ADDED
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
var markers_exports = {};
|
|
20
|
+
__export(markers_exports, {
|
|
21
|
+
__resetMarkers: () => __resetMarkers,
|
|
22
|
+
__setMarkerDeps: () => __setMarkerDeps,
|
|
23
|
+
emitMarker: () => emitMarker,
|
|
24
|
+
emitMarkerOnce: () => emitMarkerOnce
|
|
25
|
+
});
|
|
26
|
+
module.exports = __toCommonJS(markers_exports);
|
|
27
|
+
var import_sandboxUtils = require("./sandboxUtils");
|
|
28
|
+
var import_irMarkers = require("./irMarkers");
|
|
29
|
+
const realNow = () => typeof performance !== "undefined" && typeof performance.now === "function" ? performance.now() : Date.now();
|
|
30
|
+
const defaultDeps = { send: import_sandboxUtils.sendMessage, now: realNow };
|
|
31
|
+
let deps = defaultDeps;
|
|
32
|
+
const emitted = /* @__PURE__ */ new Set();
|
|
33
|
+
function emitMarker(name, attrs) {
|
|
34
|
+
if (!(0, import_irMarkers.isIrMarkerName)(name)) return;
|
|
35
|
+
try {
|
|
36
|
+
deps.send("ir-marker", { name, at: deps.now(), ...attrs !== void 0 ? { attrs } : {} });
|
|
37
|
+
} catch {
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
function emitMarkerOnce(name, attrs) {
|
|
41
|
+
if (emitted.has(name)) return;
|
|
42
|
+
emitted.add(name);
|
|
43
|
+
emitMarker(name, attrs);
|
|
44
|
+
}
|
|
45
|
+
function __setMarkerDeps(d) {
|
|
46
|
+
deps = { ...defaultDeps, ...d };
|
|
47
|
+
}
|
|
48
|
+
function __resetMarkers() {
|
|
49
|
+
deps = defaultDeps;
|
|
50
|
+
emitted.clear();
|
|
51
|
+
}
|
|
52
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
53
|
+
0 && (module.exports = {
|
|
54
|
+
__resetMarkers,
|
|
55
|
+
__setMarkerDeps,
|
|
56
|
+
emitMarker,
|
|
57
|
+
emitMarkerOnce
|
|
58
|
+
});
|
|
59
|
+
//# sourceMappingURL=markers.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/markers.ts"],"sourcesContent":["// Runtime emission of the boot `ir.*` markers (LOAD_PROFILING_SPEC §3/§3.2, R3-46).\n//\n// The host already MERGED the receive end: it validates a forwarded\n// `{ type:'ir-marker', name, at, attrs? }` against the LP-5 allowlist\n// (`irMarkers.ts`) and brackets request→interactive, treating an accepted\n// `ir.interactive` as the root-render-commit signal (site-main\n// `routePerfMessage`/`perfTimeline`). This module is the SANDBOX-side emitter for\n// the boot marks the SDK owns — `ir.fmp` (first meaningful paint) and\n// `ir.interactive` (root render commit) — forwarded over the same transport as\n// `reportReady()` (`ready.ts`). The per-marker timestamp is the sandbox-relative\n// `performance.now()` at emission (§3.2).\n//\n// Mirrors `ready.ts`'s dependency seam so the emission is unit-testable without a\n// host transport, and is idempotent per name so React StrictMode's double-invoke\n// (or any re-commit) can't mint a boot mark twice.\nimport { sendMessage as defaultSend } from './sandboxUtils';\nimport { isIrMarkerName, type IrMarkerName } from './irMarkers';\n\ninterface MarkerDeps {\n send: (type: string, data?: Record<string, unknown>) => void;\n now: () => number;\n}\n\nconst realNow = (): number =>\n typeof performance !== 'undefined' && typeof performance.now === 'function'\n ? performance.now()\n : Date.now();\n\nconst defaultDeps: MarkerDeps = { send: defaultSend, now: realNow };\n\nlet deps: MarkerDeps = defaultDeps;\nconst emitted = new Set<string>();\n\n/**\n * Forward one `ir.*` marker to the host (`ir-marker`). The host re-validates against\n * the allowlist, so a bad name/attr is dropped there; we only emit names the SDK\n * itself owns. A transport that isn't ready yet is swallowed — a missing boot mark\n * must never break the app's boot.\n */\nexport function emitMarker(name: IrMarkerName, attrs?: Record<string, unknown>): void {\n if (!isIrMarkerName(name)) return;\n try {\n deps.send('ir-marker', { name, at: deps.now(), ...(attrs !== undefined ? { attrs } : {}) });\n } catch {\n /* transport not ready — boot continues; the host simply lacks this mark */\n }\n}\n\n/** Emit a boot one-shot at most once per name (idempotent across StrictMode/re-commit). */\nexport function emitMarkerOnce(name: IrMarkerName, attrs?: Record<string, unknown>): void {\n if (emitted.has(name)) return;\n emitted.add(name);\n emitMarker(name, attrs);\n}\n\n/** Test seam: override the transport/clock. */\nexport function __setMarkerDeps(d: Partial<MarkerDeps>): void {\n deps = { ...defaultDeps, ...d };\n}\n\n/** Test seam: reset module state (the once-guard + deps) between cases. */\nexport function __resetMarkers(): void {\n deps = defaultDeps;\n emitted.clear();\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAeA,0BAA2C;AAC3C,uBAAkD;AAOlD,MAAM,UAAU,MACd,OAAO,gBAAgB,eAAe,OAAO,YAAY,QAAQ,aAC7D,YAAY,IAAI,IAChB,KAAK,IAAI;AAEf,MAAM,cAA0B,EAAE,MAAM,oBAAAA,aAAa,KAAK,QAAQ;AAElE,IAAI,OAAmB;AACvB,MAAM,UAAU,oBAAI,IAAY;AAQzB,SAAS,WAAW,MAAoB,OAAuC;AACpF,MAAI,KAAC,iCAAe,IAAI,EAAG;AAC3B,MAAI;AACF,SAAK,KAAK,aAAa,EAAE,MAAM,IAAI,KAAK,IAAI,GAAG,GAAI,UAAU,SAAY,EAAE,MAAM,IAAI,CAAC,EAAG,CAAC;AAAA,EAC5F,QAAQ;AAAA,EAER;AACF;AAGO,SAAS,eAAe,MAAoB,OAAuC;AACxF,MAAI,QAAQ,IAAI,IAAI,EAAG;AACvB,UAAQ,IAAI,IAAI;AAChB,aAAW,MAAM,KAAK;AACxB;AAGO,SAAS,gBAAgB,GAA8B;AAC5D,SAAO,EAAE,GAAG,aAAa,GAAG,EAAE;AAChC;AAGO,SAAS,iBAAuB;AACrC,SAAO;AACP,UAAQ,MAAM;AAChB;","names":["defaultSend"]}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { IrMarkerName } from './irMarkers.cjs';
|
|
2
|
+
|
|
3
|
+
interface MarkerDeps {
|
|
4
|
+
send: (type: string, data?: Record<string, unknown>) => void;
|
|
5
|
+
now: () => number;
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* Forward one `ir.*` marker to the host (`ir-marker`). The host re-validates against
|
|
9
|
+
* the allowlist, so a bad name/attr is dropped there; we only emit names the SDK
|
|
10
|
+
* itself owns. A transport that isn't ready yet is swallowed — a missing boot mark
|
|
11
|
+
* must never break the app's boot.
|
|
12
|
+
*/
|
|
13
|
+
declare function emitMarker(name: IrMarkerName, attrs?: Record<string, unknown>): void;
|
|
14
|
+
/** Emit a boot one-shot at most once per name (idempotent across StrictMode/re-commit). */
|
|
15
|
+
declare function emitMarkerOnce(name: IrMarkerName, attrs?: Record<string, unknown>): void;
|
|
16
|
+
/** Test seam: override the transport/clock. */
|
|
17
|
+
declare function __setMarkerDeps(d: Partial<MarkerDeps>): void;
|
|
18
|
+
/** Test seam: reset module state (the once-guard + deps) between cases. */
|
|
19
|
+
declare function __resetMarkers(): void;
|
|
20
|
+
|
|
21
|
+
export { __resetMarkers, __setMarkerDeps, emitMarker, emitMarkerOnce };
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { IrMarkerName } from './irMarkers.js';
|
|
2
|
+
|
|
3
|
+
interface MarkerDeps {
|
|
4
|
+
send: (type: string, data?: Record<string, unknown>) => void;
|
|
5
|
+
now: () => number;
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* Forward one `ir.*` marker to the host (`ir-marker`). The host re-validates against
|
|
9
|
+
* the allowlist, so a bad name/attr is dropped there; we only emit names the SDK
|
|
10
|
+
* itself owns. A transport that isn't ready yet is swallowed — a missing boot mark
|
|
11
|
+
* must never break the app's boot.
|
|
12
|
+
*/
|
|
13
|
+
declare function emitMarker(name: IrMarkerName, attrs?: Record<string, unknown>): void;
|
|
14
|
+
/** Emit a boot one-shot at most once per name (idempotent across StrictMode/re-commit). */
|
|
15
|
+
declare function emitMarkerOnce(name: IrMarkerName, attrs?: Record<string, unknown>): void;
|
|
16
|
+
/** Test seam: override the transport/clock. */
|
|
17
|
+
declare function __setMarkerDeps(d: Partial<MarkerDeps>): void;
|
|
18
|
+
/** Test seam: reset module state (the once-guard + deps) between cases. */
|
|
19
|
+
declare function __resetMarkers(): void;
|
|
20
|
+
|
|
21
|
+
export { __resetMarkers, __setMarkerDeps, emitMarker, emitMarkerOnce };
|
package/dist/markers.js
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { sendMessage as defaultSend } from "./sandboxUtils";
|
|
2
|
+
import { isIrMarkerName } from "./irMarkers";
|
|
3
|
+
const realNow = () => typeof performance !== "undefined" && typeof performance.now === "function" ? performance.now() : Date.now();
|
|
4
|
+
const defaultDeps = { send: defaultSend, now: realNow };
|
|
5
|
+
let deps = defaultDeps;
|
|
6
|
+
const emitted = /* @__PURE__ */ new Set();
|
|
7
|
+
function emitMarker(name, attrs) {
|
|
8
|
+
if (!isIrMarkerName(name)) return;
|
|
9
|
+
try {
|
|
10
|
+
deps.send("ir-marker", { name, at: deps.now(), ...attrs !== void 0 ? { attrs } : {} });
|
|
11
|
+
} catch {
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
function emitMarkerOnce(name, attrs) {
|
|
15
|
+
if (emitted.has(name)) return;
|
|
16
|
+
emitted.add(name);
|
|
17
|
+
emitMarker(name, attrs);
|
|
18
|
+
}
|
|
19
|
+
function __setMarkerDeps(d) {
|
|
20
|
+
deps = { ...defaultDeps, ...d };
|
|
21
|
+
}
|
|
22
|
+
function __resetMarkers() {
|
|
23
|
+
deps = defaultDeps;
|
|
24
|
+
emitted.clear();
|
|
25
|
+
}
|
|
26
|
+
export {
|
|
27
|
+
__resetMarkers,
|
|
28
|
+
__setMarkerDeps,
|
|
29
|
+
emitMarker,
|
|
30
|
+
emitMarkerOnce
|
|
31
|
+
};
|
|
32
|
+
//# sourceMappingURL=markers.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/markers.ts"],"sourcesContent":["// Runtime emission of the boot `ir.*` markers (LOAD_PROFILING_SPEC §3/§3.2, R3-46).\n//\n// The host already MERGED the receive end: it validates a forwarded\n// `{ type:'ir-marker', name, at, attrs? }` against the LP-5 allowlist\n// (`irMarkers.ts`) and brackets request→interactive, treating an accepted\n// `ir.interactive` as the root-render-commit signal (site-main\n// `routePerfMessage`/`perfTimeline`). This module is the SANDBOX-side emitter for\n// the boot marks the SDK owns — `ir.fmp` (first meaningful paint) and\n// `ir.interactive` (root render commit) — forwarded over the same transport as\n// `reportReady()` (`ready.ts`). The per-marker timestamp is the sandbox-relative\n// `performance.now()` at emission (§3.2).\n//\n// Mirrors `ready.ts`'s dependency seam so the emission is unit-testable without a\n// host transport, and is idempotent per name so React StrictMode's double-invoke\n// (or any re-commit) can't mint a boot mark twice.\nimport { sendMessage as defaultSend } from './sandboxUtils';\nimport { isIrMarkerName, type IrMarkerName } from './irMarkers';\n\ninterface MarkerDeps {\n send: (type: string, data?: Record<string, unknown>) => void;\n now: () => number;\n}\n\nconst realNow = (): number =>\n typeof performance !== 'undefined' && typeof performance.now === 'function'\n ? performance.now()\n : Date.now();\n\nconst defaultDeps: MarkerDeps = { send: defaultSend, now: realNow };\n\nlet deps: MarkerDeps = defaultDeps;\nconst emitted = new Set<string>();\n\n/**\n * Forward one `ir.*` marker to the host (`ir-marker`). The host re-validates against\n * the allowlist, so a bad name/attr is dropped there; we only emit names the SDK\n * itself owns. A transport that isn't ready yet is swallowed — a missing boot mark\n * must never break the app's boot.\n */\nexport function emitMarker(name: IrMarkerName, attrs?: Record<string, unknown>): void {\n if (!isIrMarkerName(name)) return;\n try {\n deps.send('ir-marker', { name, at: deps.now(), ...(attrs !== undefined ? { attrs } : {}) });\n } catch {\n /* transport not ready — boot continues; the host simply lacks this mark */\n }\n}\n\n/** Emit a boot one-shot at most once per name (idempotent across StrictMode/re-commit). */\nexport function emitMarkerOnce(name: IrMarkerName, attrs?: Record<string, unknown>): void {\n if (emitted.has(name)) return;\n emitted.add(name);\n emitMarker(name, attrs);\n}\n\n/** Test seam: override the transport/clock. */\nexport function __setMarkerDeps(d: Partial<MarkerDeps>): void {\n deps = { ...defaultDeps, ...d };\n}\n\n/** Test seam: reset module state (the once-guard + deps) between cases. */\nexport function __resetMarkers(): void {\n deps = defaultDeps;\n emitted.clear();\n}\n"],"mappings":"AAeA,SAAS,eAAe,mBAAmB;AAC3C,SAAS,sBAAyC;AAOlD,MAAM,UAAU,MACd,OAAO,gBAAgB,eAAe,OAAO,YAAY,QAAQ,aAC7D,YAAY,IAAI,IAChB,KAAK,IAAI;AAEf,MAAM,cAA0B,EAAE,MAAM,aAAa,KAAK,QAAQ;AAElE,IAAI,OAAmB;AACvB,MAAM,UAAU,oBAAI,IAAY;AAQzB,SAAS,WAAW,MAAoB,OAAuC;AACpF,MAAI,CAAC,eAAe,IAAI,EAAG;AAC3B,MAAI;AACF,SAAK,KAAK,aAAa,EAAE,MAAM,IAAI,KAAK,IAAI,GAAG,GAAI,UAAU,SAAY,EAAE,MAAM,IAAI,CAAC,EAAG,CAAC;AAAA,EAC5F,QAAQ;AAAA,EAER;AACF;AAGO,SAAS,eAAe,MAAoB,OAAuC;AACxF,MAAI,QAAQ,IAAI,IAAI,EAAG;AACvB,UAAQ,IAAI,IAAI;AAChB,aAAW,MAAM,KAAK;AACxB;AAGO,SAAS,gBAAgB,GAA8B;AAC5D,SAAO,EAAE,GAAG,aAAa,GAAG,EAAE;AAChC;AAGO,SAAS,iBAAuB;AACrC,SAAO;AACP,UAAQ,MAAM;AAChB;","names":[]}
|
package/dist/region.cjs
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
var region_exports = {};
|
|
20
|
+
__export(region_exports, {
|
|
21
|
+
getRegion: () => getRegion,
|
|
22
|
+
useRegion: () => useRegion
|
|
23
|
+
});
|
|
24
|
+
module.exports = __toCommonJS(region_exports);
|
|
25
|
+
var import_react = require("react");
|
|
26
|
+
var import_hostRuntime = require("./hostRuntime");
|
|
27
|
+
const getRegion = () => (0, import_hostRuntime.getHostRuntime)()?.region ?? null;
|
|
28
|
+
const useRegion = () => {
|
|
29
|
+
const [region, setRegion] = (0, import_react.useState)(getRegion);
|
|
30
|
+
(0, import_react.useEffect)(() => {
|
|
31
|
+
if (region !== null) return;
|
|
32
|
+
let live = true;
|
|
33
|
+
void (0, import_hostRuntime.getHostRuntime)()?.ready?.then(() => {
|
|
34
|
+
if (live) setRegion(getRegion());
|
|
35
|
+
});
|
|
36
|
+
return () => {
|
|
37
|
+
live = false;
|
|
38
|
+
};
|
|
39
|
+
}, [region]);
|
|
40
|
+
return region;
|
|
41
|
+
};
|
|
42
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
43
|
+
0 && (module.exports = {
|
|
44
|
+
getRegion,
|
|
45
|
+
useRegion
|
|
46
|
+
});
|
|
47
|
+
//# sourceMappingURL=region.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/region.ts"],"sourcesContent":["// Region-awareness (UI_AS_APPS_SPEC §4.1). The host can mount the SAME app in more\n// than one chrome region — e.g. the agents activity puts one app in BOTH the panel\n// slot (`panel.agent`, the conversation list) and the stage slot\n// (`stage.conversation`, the selected conversation). `getRegion()` lets that one app\n// tell the slots apart and render the right view.\n//\n// This is descriptive only: the region id is a non-secret string the host already\n// knows. It grants nothing and gates nothing — it just names where the app is\n// mounted. The host reports it on the §4 discovery global beside `appMountPath`.\n\nimport { useEffect, useState } from 'react';\nimport { getHostRuntime } from './hostRuntime';\n\n/**\n * The chrome region this app instance is mounted in (e.g. `\"panel.agent\"`,\n * `\"stage.conversation\"`), or `null` when unknown — a standalone app, local\n * `vite dev`, or an older host that doesn't report it.\n */\nexport const getRegion = (): string | null => getHostRuntime()?.region ?? null;\n\n/**\n * React hook form of {@link getRegion}. The region is fixed for an app instance's\n * lifetime, but the discovery global can arrive just after first paint, so this\n * re-reads once the host runtime's `ready` promise resolves.\n */\nexport const useRegion = (): string | null => {\n const [region, setRegion] = useState<string | null>(getRegion);\n useEffect(() => {\n if (region !== null) return;\n let live = true;\n void getHostRuntime()?.ready?.then(() => {\n if (live) setRegion(getRegion());\n });\n return () => {\n live = false;\n };\n }, [region]);\n return region;\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAUA,mBAAoC;AACpC,yBAA+B;AAOxB,MAAM,YAAY,UAAqB,mCAAe,GAAG,UAAU;AAOnE,MAAM,YAAY,MAAqB;AAC5C,QAAM,CAAC,QAAQ,SAAS,QAAI,uBAAwB,SAAS;AAC7D,8BAAU,MAAM;AACd,QAAI,WAAW,KAAM;AACrB,QAAI,OAAO;AACX,aAAK,mCAAe,GAAG,OAAO,KAAK,MAAM;AACvC,UAAI,KAAM,WAAU,UAAU,CAAC;AAAA,IACjC,CAAC;AACD,WAAO,MAAM;AACX,aAAO;AAAA,IACT;AAAA,EACF,GAAG,CAAC,MAAM,CAAC;AACX,SAAO;AACT;","names":[]}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The chrome region this app instance is mounted in (e.g. `"panel.agent"`,
|
|
3
|
+
* `"stage.conversation"`), or `null` when unknown — a standalone app, local
|
|
4
|
+
* `vite dev`, or an older host that doesn't report it.
|
|
5
|
+
*/
|
|
6
|
+
declare const getRegion: () => string | null;
|
|
7
|
+
/**
|
|
8
|
+
* React hook form of {@link getRegion}. The region is fixed for an app instance's
|
|
9
|
+
* lifetime, but the discovery global can arrive just after first paint, so this
|
|
10
|
+
* re-reads once the host runtime's `ready` promise resolves.
|
|
11
|
+
*/
|
|
12
|
+
declare const useRegion: () => string | null;
|
|
13
|
+
|
|
14
|
+
export { getRegion, useRegion };
|
package/dist/region.d.ts
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The chrome region this app instance is mounted in (e.g. `"panel.agent"`,
|
|
3
|
+
* `"stage.conversation"`), or `null` when unknown — a standalone app, local
|
|
4
|
+
* `vite dev`, or an older host that doesn't report it.
|
|
5
|
+
*/
|
|
6
|
+
declare const getRegion: () => string | null;
|
|
7
|
+
/**
|
|
8
|
+
* React hook form of {@link getRegion}. The region is fixed for an app instance's
|
|
9
|
+
* lifetime, but the discovery global can arrive just after first paint, so this
|
|
10
|
+
* re-reads once the host runtime's `ready` promise resolves.
|
|
11
|
+
*/
|
|
12
|
+
declare const useRegion: () => string | null;
|
|
13
|
+
|
|
14
|
+
export { getRegion, useRegion };
|
package/dist/region.js
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { useEffect, useState } from "react";
|
|
2
|
+
import { getHostRuntime } from "./hostRuntime";
|
|
3
|
+
const getRegion = () => getHostRuntime()?.region ?? null;
|
|
4
|
+
const useRegion = () => {
|
|
5
|
+
const [region, setRegion] = useState(getRegion);
|
|
6
|
+
useEffect(() => {
|
|
7
|
+
if (region !== null) return;
|
|
8
|
+
let live = true;
|
|
9
|
+
void getHostRuntime()?.ready?.then(() => {
|
|
10
|
+
if (live) setRegion(getRegion());
|
|
11
|
+
});
|
|
12
|
+
return () => {
|
|
13
|
+
live = false;
|
|
14
|
+
};
|
|
15
|
+
}, [region]);
|
|
16
|
+
return region;
|
|
17
|
+
};
|
|
18
|
+
export {
|
|
19
|
+
getRegion,
|
|
20
|
+
useRegion
|
|
21
|
+
};
|
|
22
|
+
//# sourceMappingURL=region.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/region.ts"],"sourcesContent":["// Region-awareness (UI_AS_APPS_SPEC §4.1). The host can mount the SAME app in more\n// than one chrome region — e.g. the agents activity puts one app in BOTH the panel\n// slot (`panel.agent`, the conversation list) and the stage slot\n// (`stage.conversation`, the selected conversation). `getRegion()` lets that one app\n// tell the slots apart and render the right view.\n//\n// This is descriptive only: the region id is a non-secret string the host already\n// knows. It grants nothing and gates nothing — it just names where the app is\n// mounted. The host reports it on the §4 discovery global beside `appMountPath`.\n\nimport { useEffect, useState } from 'react';\nimport { getHostRuntime } from './hostRuntime';\n\n/**\n * The chrome region this app instance is mounted in (e.g. `\"panel.agent\"`,\n * `\"stage.conversation\"`), or `null` when unknown — a standalone app, local\n * `vite dev`, or an older host that doesn't report it.\n */\nexport const getRegion = (): string | null => getHostRuntime()?.region ?? null;\n\n/**\n * React hook form of {@link getRegion}. The region is fixed for an app instance's\n * lifetime, but the discovery global can arrive just after first paint, so this\n * re-reads once the host runtime's `ready` promise resolves.\n */\nexport const useRegion = (): string | null => {\n const [region, setRegion] = useState<string | null>(getRegion);\n useEffect(() => {\n if (region !== null) return;\n let live = true;\n void getHostRuntime()?.ready?.then(() => {\n if (live) setRegion(getRegion());\n });\n return () => {\n live = false;\n };\n }, [region]);\n return region;\n};\n"],"mappings":"AAUA,SAAS,WAAW,gBAAgB;AACpC,SAAS,sBAAsB;AAOxB,MAAM,YAAY,MAAqB,eAAe,GAAG,UAAU;AAOnE,MAAM,YAAY,MAAqB;AAC5C,QAAM,CAAC,QAAQ,SAAS,IAAI,SAAwB,SAAS;AAC7D,YAAU,MAAM;AACd,QAAI,WAAW,KAAM;AACrB,QAAI,OAAO;AACX,SAAK,eAAe,GAAG,OAAO,KAAK,MAAM;AACvC,UAAI,KAAM,WAAU,UAAU,CAAC;AAAA,IACjC,CAAC;AACD,WAAO,MAAM;AACX,aAAO;AAAA,IACT;AAAA,EACF,GAAG,CAAC,MAAM,CAAC;AACX,SAAO;AACT;","names":[]}
|
package/dist/testing.cjs
ADDED
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
var testing_exports = {};
|
|
20
|
+
__export(testing_exports, {
|
|
21
|
+
createMockHost: () => createMockHost
|
|
22
|
+
});
|
|
23
|
+
module.exports = __toCommonJS(testing_exports);
|
|
24
|
+
const GLOBAL_KEY = "__immediatelyRun__";
|
|
25
|
+
function createMockHost() {
|
|
26
|
+
const handlers = /* @__PURE__ */ new Set();
|
|
27
|
+
const sent = [];
|
|
28
|
+
const protocolCalls = [];
|
|
29
|
+
const responders = /* @__PURE__ */ new Map();
|
|
30
|
+
const key = (protocol, method) => `${protocol}::${method}`;
|
|
31
|
+
const transport = {
|
|
32
|
+
sendMessage(type, data = {}) {
|
|
33
|
+
sent.push({ type, data });
|
|
34
|
+
},
|
|
35
|
+
protocolRequest(protocol, method, params) {
|
|
36
|
+
protocolCalls.push({ protocol, method, params });
|
|
37
|
+
const responder = responders.get(key(protocol, method));
|
|
38
|
+
if (!responder) {
|
|
39
|
+
return Promise.reject(
|
|
40
|
+
new Error(`mockHost: no stub for protocolRequest('${protocol}', '${method}')`)
|
|
41
|
+
);
|
|
42
|
+
}
|
|
43
|
+
return Promise.resolve().then(() => responder(params));
|
|
44
|
+
},
|
|
45
|
+
onMessage(handler) {
|
|
46
|
+
handlers.add(handler);
|
|
47
|
+
return { dispose: () => handlers.delete(handler) };
|
|
48
|
+
}
|
|
49
|
+
};
|
|
50
|
+
const g = globalThis;
|
|
51
|
+
return {
|
|
52
|
+
transport,
|
|
53
|
+
install(extras = {}) {
|
|
54
|
+
g[GLOBAL_KEY] = { ...extras, transport };
|
|
55
|
+
},
|
|
56
|
+
uninstall() {
|
|
57
|
+
delete g[GLOBAL_KEY];
|
|
58
|
+
},
|
|
59
|
+
emit(msg) {
|
|
60
|
+
for (const handler of [...handlers]) handler(msg);
|
|
61
|
+
},
|
|
62
|
+
stubProtocol(protocol, method, responder) {
|
|
63
|
+
responders.set(key(protocol, method), responder);
|
|
64
|
+
},
|
|
65
|
+
sent,
|
|
66
|
+
protocolCalls,
|
|
67
|
+
handlerCount: () => handlers.size
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
71
|
+
0 && (module.exports = {
|
|
72
|
+
createMockHost
|
|
73
|
+
});
|
|
74
|
+
//# sourceMappingURL=testing.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/testing.ts"],"sourcesContent":["// Public testing utility — `@immediately-run/sdk/testing` (TESTING_AUTOMATION_SPEC\n// §3/§7). A mock host transport so apps built on this SDK can unit-test their host\n// interaction in CI, with no live bundler/host: drive the SDK's REAL transport path\n// by installing this at the §4 discovery global, then `emit()` host→app pushes and\n// assert your app reacts.\n//\n// import { createMockHost } from '@immediately-run/sdk/testing';\n// const host = createMockHost();\n// host.install(); // SDK now resolves this transport\n// host.stubProtocol('spaces', 'list', () => ({ ok: true, data: [] }));\n// // …render your app / call SDK functions…\n// host.emit({ type: 'mount-add', mount: { path: '/spaces/a', type: 'firestore', id: 'a' } });\n// expect(host.sent).toContainEqual({ type: 'request-mounts', data: {} });\n// host.uninstall();\n//\n// It implements the `sandboxUtils` host transport (sendMessage / protocolRequest /\n// onMessage), so tests exercise the actual `transport()` resolution, the\n// `addListener` type-filter, and `protocolRequest` round-trips — higher fidelity\n// than mocking `./sandboxUtils` wholesale.\n\n/** A message pushed host → app, as it arrives on `onMessage`. */\nexport interface HostMessage {\n type: string;\n [k: string]: unknown;\n}\n\n/** An outbound `sendMessage` captured by the mock. */\nexport interface SentMessage {\n type: string;\n data: Record<string, unknown>;\n}\n\n/** An outbound `protocolRequest` captured by the mock. */\nexport interface ProtocolCall {\n protocol: string;\n method: string;\n params: unknown[];\n}\n\n/** Responder stub for a `protocolRequest(protocol, method, …)`. */\nexport type ProtocolResponder = (params: unknown[]) => unknown;\n\n/** Extra §4 discovery-global fields to publish alongside `transport` on install. */\nexport interface MockHostGlobalExtras {\n runtimeVersion?: string;\n protocolVersion?: string;\n appMountPath?: string;\n}\n\ninterface ImmediatelyRunGlobal extends MockHostGlobalExtras {\n transport?: unknown;\n}\n\n/** The controllable mock host returned by {@link createMockHost}. */\nexport interface MockHost {\n /** The §4 host transport object (also published on the global by `install`). */\n transport: {\n sendMessage(type: string, data?: Record<string, unknown>): void;\n protocolRequest(protocol: string, method: string, params: unknown[]): Promise<unknown>;\n onMessage(handler: (msg: HostMessage) => void): { dispose(): void };\n };\n /** Publish the transport at `globalThis.__immediatelyRun__` (npm-fetched path). */\n install(extras?: MockHostGlobalExtras): void;\n /** Remove the discovery global (call in `afterEach`). */\n uninstall(): void;\n /** Simulate a host → app push; delivered to every live `onMessage` handler. */\n emit(msg: HostMessage): void;\n /** Register a response for a `protocolRequest`; unstubbed calls reject. */\n stubProtocol(protocol: string, method: string, responder: ProtocolResponder): void;\n /** Every `sendMessage` the SDK made, in order. */\n readonly sent: SentMessage[];\n /** Every `protocolRequest` the SDK made, in order. */\n readonly protocolCalls: ProtocolCall[];\n /** Count of live `onMessage` listeners (leak checks). */\n handlerCount(): number;\n}\n\nconst GLOBAL_KEY = '__immediatelyRun__';\n\n/** Build a controllable mock host. Nothing is global until you call `install()`. */\nexport function createMockHost(): MockHost {\n const handlers = new Set<(msg: HostMessage) => void>();\n const sent: SentMessage[] = [];\n const protocolCalls: ProtocolCall[] = [];\n const responders = new Map<string, ProtocolResponder>();\n const key = (protocol: string, method: string) => `${protocol}::${method}`;\n\n const transport: MockHost['transport'] = {\n sendMessage(type, data = {}) {\n sent.push({ type, data });\n },\n protocolRequest(protocol, method, params) {\n protocolCalls.push({ protocol, method, params });\n const responder = responders.get(key(protocol, method));\n if (!responder) {\n return Promise.reject(\n new Error(`mockHost: no stub for protocolRequest('${protocol}', '${method}')`),\n );\n }\n // Resolve async so callers observe real microtask ordering.\n return Promise.resolve().then(() => responder(params));\n },\n onMessage(handler) {\n handlers.add(handler);\n return { dispose: () => handlers.delete(handler) };\n },\n };\n\n const g = globalThis as { [GLOBAL_KEY]?: ImmediatelyRunGlobal };\n\n return {\n transport,\n install(extras = {}) {\n g[GLOBAL_KEY] = { ...extras, transport };\n },\n uninstall() {\n delete g[GLOBAL_KEY];\n },\n emit(msg) {\n // Copy so a handler that unsubscribes mid-emit doesn't mutate the live set.\n for (const handler of [...handlers]) handler(msg);\n },\n stubProtocol(protocol, method, responder) {\n responders.set(key(protocol, method), responder);\n },\n sent,\n protocolCalls,\n handlerCount: () => handlers.size,\n };\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AA6EA,MAAM,aAAa;AAGZ,SAAS,iBAA2B;AACzC,QAAM,WAAW,oBAAI,IAAgC;AACrD,QAAM,OAAsB,CAAC;AAC7B,QAAM,gBAAgC,CAAC;AACvC,QAAM,aAAa,oBAAI,IAA+B;AACtD,QAAM,MAAM,CAAC,UAAkB,WAAmB,GAAG,QAAQ,KAAK,MAAM;AAExE,QAAM,YAAmC;AAAA,IACvC,YAAY,MAAM,OAAO,CAAC,GAAG;AAC3B,WAAK,KAAK,EAAE,MAAM,KAAK,CAAC;AAAA,IAC1B;AAAA,IACA,gBAAgB,UAAU,QAAQ,QAAQ;AACxC,oBAAc,KAAK,EAAE,UAAU,QAAQ,OAAO,CAAC;AAC/C,YAAM,YAAY,WAAW,IAAI,IAAI,UAAU,MAAM,CAAC;AACtD,UAAI,CAAC,WAAW;AACd,eAAO,QAAQ;AAAA,UACb,IAAI,MAAM,0CAA0C,QAAQ,OAAO,MAAM,IAAI;AAAA,QAC/E;AAAA,MACF;AAEA,aAAO,QAAQ,QAAQ,EAAE,KAAK,MAAM,UAAU,MAAM,CAAC;AAAA,IACvD;AAAA,IACA,UAAU,SAAS;AACjB,eAAS,IAAI,OAAO;AACpB,aAAO,EAAE,SAAS,MAAM,SAAS,OAAO,OAAO,EAAE;AAAA,IACnD;AAAA,EACF;AAEA,QAAM,IAAI;AAEV,SAAO;AAAA,IACL;AAAA,IACA,QAAQ,SAAS,CAAC,GAAG;AACnB,QAAE,UAAU,IAAI,EAAE,GAAG,QAAQ,UAAU;AAAA,IACzC;AAAA,IACA,YAAY;AACV,aAAO,EAAE,UAAU;AAAA,IACrB;AAAA,IACA,KAAK,KAAK;AAER,iBAAW,WAAW,CAAC,GAAG,QAAQ,EAAG,SAAQ,GAAG;AAAA,IAClD;AAAA,IACA,aAAa,UAAU,QAAQ,WAAW;AACxC,iBAAW,IAAI,IAAI,UAAU,MAAM,GAAG,SAAS;AAAA,IACjD;AAAA,IACA;AAAA,IACA;AAAA,IACA,cAAc,MAAM,SAAS;AAAA,EAC/B;AACF;","names":[]}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
/** A message pushed host → app, as it arrives on `onMessage`. */
|
|
2
|
+
interface HostMessage {
|
|
3
|
+
type: string;
|
|
4
|
+
[k: string]: unknown;
|
|
5
|
+
}
|
|
6
|
+
/** An outbound `sendMessage` captured by the mock. */
|
|
7
|
+
interface SentMessage {
|
|
8
|
+
type: string;
|
|
9
|
+
data: Record<string, unknown>;
|
|
10
|
+
}
|
|
11
|
+
/** An outbound `protocolRequest` captured by the mock. */
|
|
12
|
+
interface ProtocolCall {
|
|
13
|
+
protocol: string;
|
|
14
|
+
method: string;
|
|
15
|
+
params: unknown[];
|
|
16
|
+
}
|
|
17
|
+
/** Responder stub for a `protocolRequest(protocol, method, …)`. */
|
|
18
|
+
type ProtocolResponder = (params: unknown[]) => unknown;
|
|
19
|
+
/** Extra §4 discovery-global fields to publish alongside `transport` on install. */
|
|
20
|
+
interface MockHostGlobalExtras {
|
|
21
|
+
runtimeVersion?: string;
|
|
22
|
+
protocolVersion?: string;
|
|
23
|
+
appMountPath?: string;
|
|
24
|
+
}
|
|
25
|
+
/** The controllable mock host returned by {@link createMockHost}. */
|
|
26
|
+
interface MockHost {
|
|
27
|
+
/** The §4 host transport object (also published on the global by `install`). */
|
|
28
|
+
transport: {
|
|
29
|
+
sendMessage(type: string, data?: Record<string, unknown>): void;
|
|
30
|
+
protocolRequest(protocol: string, method: string, params: unknown[]): Promise<unknown>;
|
|
31
|
+
onMessage(handler: (msg: HostMessage) => void): {
|
|
32
|
+
dispose(): void;
|
|
33
|
+
};
|
|
34
|
+
};
|
|
35
|
+
/** Publish the transport at `globalThis.__immediatelyRun__` (npm-fetched path). */
|
|
36
|
+
install(extras?: MockHostGlobalExtras): void;
|
|
37
|
+
/** Remove the discovery global (call in `afterEach`). */
|
|
38
|
+
uninstall(): void;
|
|
39
|
+
/** Simulate a host → app push; delivered to every live `onMessage` handler. */
|
|
40
|
+
emit(msg: HostMessage): void;
|
|
41
|
+
/** Register a response for a `protocolRequest`; unstubbed calls reject. */
|
|
42
|
+
stubProtocol(protocol: string, method: string, responder: ProtocolResponder): void;
|
|
43
|
+
/** Every `sendMessage` the SDK made, in order. */
|
|
44
|
+
readonly sent: SentMessage[];
|
|
45
|
+
/** Every `protocolRequest` the SDK made, in order. */
|
|
46
|
+
readonly protocolCalls: ProtocolCall[];
|
|
47
|
+
/** Count of live `onMessage` listeners (leak checks). */
|
|
48
|
+
handlerCount(): number;
|
|
49
|
+
}
|
|
50
|
+
/** Build a controllable mock host. Nothing is global until you call `install()`. */
|
|
51
|
+
declare function createMockHost(): MockHost;
|
|
52
|
+
|
|
53
|
+
export { type HostMessage, type MockHost, type MockHostGlobalExtras, type ProtocolCall, type ProtocolResponder, type SentMessage, createMockHost };
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
/** A message pushed host → app, as it arrives on `onMessage`. */
|
|
2
|
+
interface HostMessage {
|
|
3
|
+
type: string;
|
|
4
|
+
[k: string]: unknown;
|
|
5
|
+
}
|
|
6
|
+
/** An outbound `sendMessage` captured by the mock. */
|
|
7
|
+
interface SentMessage {
|
|
8
|
+
type: string;
|
|
9
|
+
data: Record<string, unknown>;
|
|
10
|
+
}
|
|
11
|
+
/** An outbound `protocolRequest` captured by the mock. */
|
|
12
|
+
interface ProtocolCall {
|
|
13
|
+
protocol: string;
|
|
14
|
+
method: string;
|
|
15
|
+
params: unknown[];
|
|
16
|
+
}
|
|
17
|
+
/** Responder stub for a `protocolRequest(protocol, method, …)`. */
|
|
18
|
+
type ProtocolResponder = (params: unknown[]) => unknown;
|
|
19
|
+
/** Extra §4 discovery-global fields to publish alongside `transport` on install. */
|
|
20
|
+
interface MockHostGlobalExtras {
|
|
21
|
+
runtimeVersion?: string;
|
|
22
|
+
protocolVersion?: string;
|
|
23
|
+
appMountPath?: string;
|
|
24
|
+
}
|
|
25
|
+
/** The controllable mock host returned by {@link createMockHost}. */
|
|
26
|
+
interface MockHost {
|
|
27
|
+
/** The §4 host transport object (also published on the global by `install`). */
|
|
28
|
+
transport: {
|
|
29
|
+
sendMessage(type: string, data?: Record<string, unknown>): void;
|
|
30
|
+
protocolRequest(protocol: string, method: string, params: unknown[]): Promise<unknown>;
|
|
31
|
+
onMessage(handler: (msg: HostMessage) => void): {
|
|
32
|
+
dispose(): void;
|
|
33
|
+
};
|
|
34
|
+
};
|
|
35
|
+
/** Publish the transport at `globalThis.__immediatelyRun__` (npm-fetched path). */
|
|
36
|
+
install(extras?: MockHostGlobalExtras): void;
|
|
37
|
+
/** Remove the discovery global (call in `afterEach`). */
|
|
38
|
+
uninstall(): void;
|
|
39
|
+
/** Simulate a host → app push; delivered to every live `onMessage` handler. */
|
|
40
|
+
emit(msg: HostMessage): void;
|
|
41
|
+
/** Register a response for a `protocolRequest`; unstubbed calls reject. */
|
|
42
|
+
stubProtocol(protocol: string, method: string, responder: ProtocolResponder): void;
|
|
43
|
+
/** Every `sendMessage` the SDK made, in order. */
|
|
44
|
+
readonly sent: SentMessage[];
|
|
45
|
+
/** Every `protocolRequest` the SDK made, in order. */
|
|
46
|
+
readonly protocolCalls: ProtocolCall[];
|
|
47
|
+
/** Count of live `onMessage` listeners (leak checks). */
|
|
48
|
+
handlerCount(): number;
|
|
49
|
+
}
|
|
50
|
+
/** Build a controllable mock host. Nothing is global until you call `install()`. */
|
|
51
|
+
declare function createMockHost(): MockHost;
|
|
52
|
+
|
|
53
|
+
export { type HostMessage, type MockHost, type MockHostGlobalExtras, type ProtocolCall, type ProtocolResponder, type SentMessage, createMockHost };
|
package/dist/testing.js
ADDED
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
const GLOBAL_KEY = "__immediatelyRun__";
|
|
2
|
+
function createMockHost() {
|
|
3
|
+
const handlers = /* @__PURE__ */ new Set();
|
|
4
|
+
const sent = [];
|
|
5
|
+
const protocolCalls = [];
|
|
6
|
+
const responders = /* @__PURE__ */ new Map();
|
|
7
|
+
const key = (protocol, method) => `${protocol}::${method}`;
|
|
8
|
+
const transport = {
|
|
9
|
+
sendMessage(type, data = {}) {
|
|
10
|
+
sent.push({ type, data });
|
|
11
|
+
},
|
|
12
|
+
protocolRequest(protocol, method, params) {
|
|
13
|
+
protocolCalls.push({ protocol, method, params });
|
|
14
|
+
const responder = responders.get(key(protocol, method));
|
|
15
|
+
if (!responder) {
|
|
16
|
+
return Promise.reject(
|
|
17
|
+
new Error(`mockHost: no stub for protocolRequest('${protocol}', '${method}')`)
|
|
18
|
+
);
|
|
19
|
+
}
|
|
20
|
+
return Promise.resolve().then(() => responder(params));
|
|
21
|
+
},
|
|
22
|
+
onMessage(handler) {
|
|
23
|
+
handlers.add(handler);
|
|
24
|
+
return { dispose: () => handlers.delete(handler) };
|
|
25
|
+
}
|
|
26
|
+
};
|
|
27
|
+
const g = globalThis;
|
|
28
|
+
return {
|
|
29
|
+
transport,
|
|
30
|
+
install(extras = {}) {
|
|
31
|
+
g[GLOBAL_KEY] = { ...extras, transport };
|
|
32
|
+
},
|
|
33
|
+
uninstall() {
|
|
34
|
+
delete g[GLOBAL_KEY];
|
|
35
|
+
},
|
|
36
|
+
emit(msg) {
|
|
37
|
+
for (const handler of [...handlers]) handler(msg);
|
|
38
|
+
},
|
|
39
|
+
stubProtocol(protocol, method, responder) {
|
|
40
|
+
responders.set(key(protocol, method), responder);
|
|
41
|
+
},
|
|
42
|
+
sent,
|
|
43
|
+
protocolCalls,
|
|
44
|
+
handlerCount: () => handlers.size
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
export {
|
|
48
|
+
createMockHost
|
|
49
|
+
};
|
|
50
|
+
//# sourceMappingURL=testing.js.map
|