@immediately-run/sdk 0.2.7 → 0.3.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/auth.cjs +13 -13
- package/dist/auth.cjs.map +1 -1
- package/dist/auth.js +13 -13
- package/dist/auth.js.map +1 -1
- package/dist/catalog.cjs +14 -26
- package/dist/catalog.cjs.map +1 -1
- package/dist/catalog.js +15 -27
- package/dist/catalog.js.map +1 -1
- package/dist/editorContext.cjs +10 -14
- package/dist/editorContext.cjs.map +1 -1
- package/dist/editorContext.js +10 -14
- package/dist/editorContext.js.map +1 -1
- package/dist/formFactor.cjs +18 -12
- package/dist/formFactor.cjs.map +1 -1
- package/dist/formFactor.js +18 -12
- package/dist/formFactor.js.map +1 -1
- package/dist/hostRuntime.cjs +35 -0
- package/dist/hostRuntime.cjs.map +1 -0
- package/dist/hostRuntime.d.cts +19 -0
- package/dist/hostRuntime.d.ts +19 -0
- package/dist/hostRuntime.js +11 -0
- package/dist/hostRuntime.js.map +1 -0
- package/dist/index.d.cts +2 -1
- package/dist/index.d.ts +2 -1
- package/dist/pushChannel.cjs +70 -0
- package/dist/pushChannel.cjs.map +1 -0
- package/dist/pushChannel.d.cts +25 -0
- package/dist/pushChannel.d.ts +25 -0
- package/dist/pushChannel.js +46 -0
- package/dist/pushChannel.js.map +1 -0
- package/dist/runtime.cjs +3 -9
- package/dist/runtime.cjs.map +1 -1
- package/dist/runtime.d.cts +4 -19
- package/dist/runtime.d.ts +4 -19
- package/dist/runtime.js +2 -8
- package/dist/runtime.js.map +1 -1
- package/dist/sandboxUtils.cjs +2 -2
- package/dist/sandboxUtils.cjs.map +1 -1
- package/dist/sandboxUtils.js +1 -1
- package/dist/sandboxUtils.js.map +1 -1
- package/dist/theme.cjs +10 -14
- package/dist/theme.cjs.map +1 -1
- package/dist/theme.js +10 -14
- package/dist/theme.js.map +1 -1
- package/package.json +5 -2
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/hostRuntime.ts"],"sourcesContent":["// Runtime-discovery global (SDK_PACKAGING_SPEC §4) — a LEAF module that imports\n// nothing, so it can be read by both `sandboxUtils` (transport resolver) and\n// `runtime` (handshake) without forming an import cycle. `sandboxUtils → runtime`\n// + `runtime → sandboxUtils` was a cycle the sandbox bundler cannot evaluate\n// (infinite re-require → \"Maximum call stack size exceeded\"); routing the shared\n// `getHostRuntime` through this leaf breaks it.\n\n/** The sandbox runtime's pre-evaluation discovery global (§4). */\nexport interface ImmediatelyRunGlobal {\n /** Sandbox-runtime protocol version (semver). */\n runtimeVersion?: string;\n /** postMessage envelope/protocol version. */\n protocolVersion?: string;\n /** The host channel the SDK talks over (MessagePort | message bus). */\n transport?: unknown;\n /** Resolves when ports arrive, if they arrive async after register-frame. */\n ready?: Promise<void>;\n}\n\n/**\n * Read the sandbox runtime's discovery global (§4), or null when absent — in which\n * case the SDK uses the current INJECTED path (`module.evaluation.*`). Lets the SDK\n * detect a host too old/new and fail closed (§6) once the global ships.\n */\nexport function getHostRuntime(): ImmediatelyRunGlobal | null {\n try {\n return (globalThis as { __immediatelyRun__?: ImmediatelyRunGlobal }).__immediatelyRun__ ?? null;\n } catch {\n return null;\n }\n}\n"],"mappings":"AAwBO,SAAS,iBAA8C;AAC5D,MAAI;AACF,WAAQ,WAA6D,sBAAsB;AAAA,EAC7F,QAAQ;AACN,WAAO;AAAA,EACT;AACF;","names":[]}
|
package/dist/index.d.cts
CHANGED
|
@@ -13,9 +13,10 @@ export { ContributeMode, ContributeOptions, ContributionEvent, ContributionResul
|
|
|
13
13
|
export { ApiMethod, getCatalog, invoke, invokeStream, onCatalogChange, useCatalog } from './catalog.cjs';
|
|
14
14
|
export { RegionMessage, onRegionMessage, postToRegion, useRegionMessage } from './ipc.cjs';
|
|
15
15
|
export { FileCap, TaskInput, cancelTask, capFile, completeTask, getTaskInput, invokeTask, useTaskInput } from './tasks.cjs';
|
|
16
|
-
export {
|
|
16
|
+
export { SDK_PROTOCOL_VERSION, SDK_VERSION, SdkHandshake, announceHandshake, sdkHandshake } from './runtime.cjs';
|
|
17
17
|
export { StreamError, StreamFrame, StreamTransport, consumeStream, protocolStream } from './protocolStream.cjs';
|
|
18
18
|
export { EvaluationContext, FileQueryResult, FilesMetadata, Metadata, MetadataQueryFunction, MetadataQueryResult, ModuleExports } from './sandboxTypes.cjs';
|
|
19
|
+
export { ImmediatelyRunGlobal, getHostRuntime } from './hostRuntime.cjs';
|
|
19
20
|
import 'react';
|
|
20
21
|
import './TinkerableContext.cjs';
|
|
21
22
|
import './RoutingSpec.cjs';
|
package/dist/index.d.ts
CHANGED
|
@@ -13,9 +13,10 @@ export { ContributeMode, ContributeOptions, ContributionEvent, ContributionResul
|
|
|
13
13
|
export { ApiMethod, getCatalog, invoke, invokeStream, onCatalogChange, useCatalog } from './catalog.js';
|
|
14
14
|
export { RegionMessage, onRegionMessage, postToRegion, useRegionMessage } from './ipc.js';
|
|
15
15
|
export { FileCap, TaskInput, cancelTask, capFile, completeTask, getTaskInput, invokeTask, useTaskInput } from './tasks.js';
|
|
16
|
-
export {
|
|
16
|
+
export { SDK_PROTOCOL_VERSION, SDK_VERSION, SdkHandshake, announceHandshake, sdkHandshake } from './runtime.js';
|
|
17
17
|
export { StreamError, StreamFrame, StreamTransport, consumeStream, protocolStream } from './protocolStream.js';
|
|
18
18
|
export { EvaluationContext, FileQueryResult, FilesMetadata, Metadata, MetadataQueryFunction, MetadataQueryResult, ModuleExports } from './sandboxTypes.js';
|
|
19
|
+
export { ImmediatelyRunGlobal, getHostRuntime } from './hostRuntime.js';
|
|
19
20
|
import 'react';
|
|
20
21
|
import './TinkerableContext.js';
|
|
21
22
|
import './RoutingSpec.js';
|
|
@@ -0,0 +1,70 @@
|
|
|
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 pushChannel_exports = {};
|
|
20
|
+
__export(pushChannel_exports, {
|
|
21
|
+
createPushChannel: () => createPushChannel
|
|
22
|
+
});
|
|
23
|
+
module.exports = __toCommonJS(pushChannel_exports);
|
|
24
|
+
var import_react = require("react");
|
|
25
|
+
var import_sandboxUtils = require("./sandboxUtils");
|
|
26
|
+
function createPushChannel(opts, transport = { sendMessage: import_sandboxUtils.sendMessage, addListener: import_sandboxUtils.addListener }) {
|
|
27
|
+
let current = opts.initial;
|
|
28
|
+
const listeners = /* @__PURE__ */ new Set();
|
|
29
|
+
let started = false;
|
|
30
|
+
const start = () => {
|
|
31
|
+
if (started) return;
|
|
32
|
+
started = true;
|
|
33
|
+
transport.addListener(opts.pushType, (msg) => {
|
|
34
|
+
const next = opts.parse(msg);
|
|
35
|
+
if (next !== void 0) {
|
|
36
|
+
current = next;
|
|
37
|
+
listeners.forEach((l) => l(current));
|
|
38
|
+
}
|
|
39
|
+
});
|
|
40
|
+
if (opts.requestType) {
|
|
41
|
+
try {
|
|
42
|
+
transport.sendMessage(opts.requestType);
|
|
43
|
+
} catch {
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
};
|
|
47
|
+
const get = () => {
|
|
48
|
+
start();
|
|
49
|
+
return current;
|
|
50
|
+
};
|
|
51
|
+
const onChange = (listener) => {
|
|
52
|
+
start();
|
|
53
|
+
listeners.add(listener);
|
|
54
|
+
listener(current);
|
|
55
|
+
return () => {
|
|
56
|
+
listeners.delete(listener);
|
|
57
|
+
};
|
|
58
|
+
};
|
|
59
|
+
const use = () => {
|
|
60
|
+
const [value, setValue] = (0, import_react.useState)(get);
|
|
61
|
+
(0, import_react.useEffect)(() => onChange(setValue), []);
|
|
62
|
+
return value;
|
|
63
|
+
};
|
|
64
|
+
return { get, onChange, use };
|
|
65
|
+
}
|
|
66
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
67
|
+
0 && (module.exports = {
|
|
68
|
+
createPushChannel
|
|
69
|
+
});
|
|
70
|
+
//# sourceMappingURL=pushChannel.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/pushChannel.ts"],"sourcesContent":["// Generic host→sandbox state channel read over the TRANSPORT\n// (SDK_PACKAGING_SPEC §4, expose-transport). The host pushes a `pushType`\n// message whenever the value changes and answers a `requestType` poll with the\n// current value — gated per-frame by the read ACL (site-main channelBridge.ts /\n// channelRouter). Historically the SDK read these values off injected sandbox\n// service objects (`module.evaluation.module.bundler.auth` etc.); this caches\n// the latest value SDK-side instead, so the SDK is self-contained and the\n// bundler services can eventually be retired.\n//\n// Every state helper (formFactor, auth, editorContext, theme, catalog) is a thin\n// wrapper over one of these — the get / onChange / use trio is identical.\nimport { useEffect, useState } from 'react';\nimport { sendMessage as defaultSend, addListener as defaultAddListener } from './sandboxUtils';\n\nexport interface PushChannel<T> {\n /** Pollable snapshot of the current value. */\n get(): T;\n /** Subscribe; invoked immediately with the current value, then on every change. Returns unsubscribe. */\n onChange(listener: (value: T) => void): () => void;\n /** React hook returning the current value, re-rendering on change. */\n use(): T;\n}\n\n/** Injectable transport — defaults to the real one; overridden in tests. */\nexport interface ChannelTransport {\n sendMessage: (type: string, data?: Record<string, unknown>) => void;\n addListener: (type: string, handler: (msg: Record<string, unknown>) => void) => () => void;\n}\n\nexport function createPushChannel<T>(\n opts: {\n /** Host→sandbox push message type (e.g. `form-factor`). */\n pushType: string;\n /** Poll message type the SDK sends to pull the current value (e.g. `request-form-factor`). */\n requestType?: string;\n /** Value assumed before the host answers — also the value when the app may not read the channel. */\n initial: T;\n /** Extract + validate the value from a push message; return `undefined` to ignore the message. */\n parse: (msg: Record<string, unknown>) => T | undefined;\n },\n transport: ChannelTransport = { sendMessage: defaultSend, addListener: defaultAddListener },\n): PushChannel<T> {\n let current = opts.initial;\n const listeners = new Set<(value: T) => void>();\n let started = false;\n\n // Lazily start on first read: register the push listener + send one poll, so a\n // late-mounting app still gets the current value. A channel the app may not\n // read is simply never answered → `initial` stands.\n const start = () => {\n if (started) return;\n started = true;\n transport.addListener(opts.pushType, (msg) => {\n const next = opts.parse(msg);\n if (next !== undefined) {\n current = next;\n listeners.forEach((l) => l(current));\n }\n });\n if (opts.requestType) {\n try {\n transport.sendMessage(opts.requestType);\n } catch {\n /* transport not ready — a proactive push will still arrive */\n }\n }\n };\n\n const get = (): T => {\n start();\n return current;\n };\n\n const onChange = (listener: (value: T) => void): (() => void) => {\n start();\n listeners.add(listener);\n listener(current);\n return () => {\n listeners.delete(listener);\n };\n };\n\n const use = (): T => {\n const [value, setValue] = useState<T>(get);\n useEffect(() => onChange(setValue), []);\n return value;\n };\n\n return { get, onChange, use };\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAWA,mBAAoC;AACpC,0BAA8E;AAiBvE,SAAS,kBACd,MAUA,YAA8B,EAAE,aAAa,oBAAAA,aAAa,aAAa,oBAAAC,YAAmB,GAC1E;AAChB,MAAI,UAAU,KAAK;AACnB,QAAM,YAAY,oBAAI,IAAwB;AAC9C,MAAI,UAAU;AAKd,QAAM,QAAQ,MAAM;AAClB,QAAI,QAAS;AACb,cAAU;AACV,cAAU,YAAY,KAAK,UAAU,CAAC,QAAQ;AAC5C,YAAM,OAAO,KAAK,MAAM,GAAG;AAC3B,UAAI,SAAS,QAAW;AACtB,kBAAU;AACV,kBAAU,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC;AAAA,MACrC;AAAA,IACF,CAAC;AACD,QAAI,KAAK,aAAa;AACpB,UAAI;AACF,kBAAU,YAAY,KAAK,WAAW;AAAA,MACxC,QAAQ;AAAA,MAER;AAAA,IACF;AAAA,EACF;AAEA,QAAM,MAAM,MAAS;AACnB,UAAM;AACN,WAAO;AAAA,EACT;AAEA,QAAM,WAAW,CAAC,aAA+C;AAC/D,UAAM;AACN,cAAU,IAAI,QAAQ;AACtB,aAAS,OAAO;AAChB,WAAO,MAAM;AACX,gBAAU,OAAO,QAAQ;AAAA,IAC3B;AAAA,EACF;AAEA,QAAM,MAAM,MAAS;AACnB,UAAM,CAAC,OAAO,QAAQ,QAAI,uBAAY,GAAG;AACzC,gCAAU,MAAM,SAAS,QAAQ,GAAG,CAAC,CAAC;AACtC,WAAO;AAAA,EACT;AAEA,SAAO,EAAE,KAAK,UAAU,IAAI;AAC9B;","names":["defaultSend","defaultAddListener"]}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
interface PushChannel<T> {
|
|
2
|
+
/** Pollable snapshot of the current value. */
|
|
3
|
+
get(): T;
|
|
4
|
+
/** Subscribe; invoked immediately with the current value, then on every change. Returns unsubscribe. */
|
|
5
|
+
onChange(listener: (value: T) => void): () => void;
|
|
6
|
+
/** React hook returning the current value, re-rendering on change. */
|
|
7
|
+
use(): T;
|
|
8
|
+
}
|
|
9
|
+
/** Injectable transport — defaults to the real one; overridden in tests. */
|
|
10
|
+
interface ChannelTransport {
|
|
11
|
+
sendMessage: (type: string, data?: Record<string, unknown>) => void;
|
|
12
|
+
addListener: (type: string, handler: (msg: Record<string, unknown>) => void) => () => void;
|
|
13
|
+
}
|
|
14
|
+
declare function createPushChannel<T>(opts: {
|
|
15
|
+
/** Host→sandbox push message type (e.g. `form-factor`). */
|
|
16
|
+
pushType: string;
|
|
17
|
+
/** Poll message type the SDK sends to pull the current value (e.g. `request-form-factor`). */
|
|
18
|
+
requestType?: string;
|
|
19
|
+
/** Value assumed before the host answers — also the value when the app may not read the channel. */
|
|
20
|
+
initial: T;
|
|
21
|
+
/** Extract + validate the value from a push message; return `undefined` to ignore the message. */
|
|
22
|
+
parse: (msg: Record<string, unknown>) => T | undefined;
|
|
23
|
+
}, transport?: ChannelTransport): PushChannel<T>;
|
|
24
|
+
|
|
25
|
+
export { type ChannelTransport, type PushChannel, createPushChannel };
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
interface PushChannel<T> {
|
|
2
|
+
/** Pollable snapshot of the current value. */
|
|
3
|
+
get(): T;
|
|
4
|
+
/** Subscribe; invoked immediately with the current value, then on every change. Returns unsubscribe. */
|
|
5
|
+
onChange(listener: (value: T) => void): () => void;
|
|
6
|
+
/** React hook returning the current value, re-rendering on change. */
|
|
7
|
+
use(): T;
|
|
8
|
+
}
|
|
9
|
+
/** Injectable transport — defaults to the real one; overridden in tests. */
|
|
10
|
+
interface ChannelTransport {
|
|
11
|
+
sendMessage: (type: string, data?: Record<string, unknown>) => void;
|
|
12
|
+
addListener: (type: string, handler: (msg: Record<string, unknown>) => void) => () => void;
|
|
13
|
+
}
|
|
14
|
+
declare function createPushChannel<T>(opts: {
|
|
15
|
+
/** Host→sandbox push message type (e.g. `form-factor`). */
|
|
16
|
+
pushType: string;
|
|
17
|
+
/** Poll message type the SDK sends to pull the current value (e.g. `request-form-factor`). */
|
|
18
|
+
requestType?: string;
|
|
19
|
+
/** Value assumed before the host answers — also the value when the app may not read the channel. */
|
|
20
|
+
initial: T;
|
|
21
|
+
/** Extract + validate the value from a push message; return `undefined` to ignore the message. */
|
|
22
|
+
parse: (msg: Record<string, unknown>) => T | undefined;
|
|
23
|
+
}, transport?: ChannelTransport): PushChannel<T>;
|
|
24
|
+
|
|
25
|
+
export { type ChannelTransport, type PushChannel, createPushChannel };
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { useEffect, useState } from "react";
|
|
2
|
+
import { sendMessage as defaultSend, addListener as defaultAddListener } from "./sandboxUtils";
|
|
3
|
+
function createPushChannel(opts, transport = { sendMessage: defaultSend, addListener: defaultAddListener }) {
|
|
4
|
+
let current = opts.initial;
|
|
5
|
+
const listeners = /* @__PURE__ */ new Set();
|
|
6
|
+
let started = false;
|
|
7
|
+
const start = () => {
|
|
8
|
+
if (started) return;
|
|
9
|
+
started = true;
|
|
10
|
+
transport.addListener(opts.pushType, (msg) => {
|
|
11
|
+
const next = opts.parse(msg);
|
|
12
|
+
if (next !== void 0) {
|
|
13
|
+
current = next;
|
|
14
|
+
listeners.forEach((l) => l(current));
|
|
15
|
+
}
|
|
16
|
+
});
|
|
17
|
+
if (opts.requestType) {
|
|
18
|
+
try {
|
|
19
|
+
transport.sendMessage(opts.requestType);
|
|
20
|
+
} catch {
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
};
|
|
24
|
+
const get = () => {
|
|
25
|
+
start();
|
|
26
|
+
return current;
|
|
27
|
+
};
|
|
28
|
+
const onChange = (listener) => {
|
|
29
|
+
start();
|
|
30
|
+
listeners.add(listener);
|
|
31
|
+
listener(current);
|
|
32
|
+
return () => {
|
|
33
|
+
listeners.delete(listener);
|
|
34
|
+
};
|
|
35
|
+
};
|
|
36
|
+
const use = () => {
|
|
37
|
+
const [value, setValue] = useState(get);
|
|
38
|
+
useEffect(() => onChange(setValue), []);
|
|
39
|
+
return value;
|
|
40
|
+
};
|
|
41
|
+
return { get, onChange, use };
|
|
42
|
+
}
|
|
43
|
+
export {
|
|
44
|
+
createPushChannel
|
|
45
|
+
};
|
|
46
|
+
//# sourceMappingURL=pushChannel.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/pushChannel.ts"],"sourcesContent":["// Generic host→sandbox state channel read over the TRANSPORT\n// (SDK_PACKAGING_SPEC §4, expose-transport). The host pushes a `pushType`\n// message whenever the value changes and answers a `requestType` poll with the\n// current value — gated per-frame by the read ACL (site-main channelBridge.ts /\n// channelRouter). Historically the SDK read these values off injected sandbox\n// service objects (`module.evaluation.module.bundler.auth` etc.); this caches\n// the latest value SDK-side instead, so the SDK is self-contained and the\n// bundler services can eventually be retired.\n//\n// Every state helper (formFactor, auth, editorContext, theme, catalog) is a thin\n// wrapper over one of these — the get / onChange / use trio is identical.\nimport { useEffect, useState } from 'react';\nimport { sendMessage as defaultSend, addListener as defaultAddListener } from './sandboxUtils';\n\nexport interface PushChannel<T> {\n /** Pollable snapshot of the current value. */\n get(): T;\n /** Subscribe; invoked immediately with the current value, then on every change. Returns unsubscribe. */\n onChange(listener: (value: T) => void): () => void;\n /** React hook returning the current value, re-rendering on change. */\n use(): T;\n}\n\n/** Injectable transport — defaults to the real one; overridden in tests. */\nexport interface ChannelTransport {\n sendMessage: (type: string, data?: Record<string, unknown>) => void;\n addListener: (type: string, handler: (msg: Record<string, unknown>) => void) => () => void;\n}\n\nexport function createPushChannel<T>(\n opts: {\n /** Host→sandbox push message type (e.g. `form-factor`). */\n pushType: string;\n /** Poll message type the SDK sends to pull the current value (e.g. `request-form-factor`). */\n requestType?: string;\n /** Value assumed before the host answers — also the value when the app may not read the channel. */\n initial: T;\n /** Extract + validate the value from a push message; return `undefined` to ignore the message. */\n parse: (msg: Record<string, unknown>) => T | undefined;\n },\n transport: ChannelTransport = { sendMessage: defaultSend, addListener: defaultAddListener },\n): PushChannel<T> {\n let current = opts.initial;\n const listeners = new Set<(value: T) => void>();\n let started = false;\n\n // Lazily start on first read: register the push listener + send one poll, so a\n // late-mounting app still gets the current value. A channel the app may not\n // read is simply never answered → `initial` stands.\n const start = () => {\n if (started) return;\n started = true;\n transport.addListener(opts.pushType, (msg) => {\n const next = opts.parse(msg);\n if (next !== undefined) {\n current = next;\n listeners.forEach((l) => l(current));\n }\n });\n if (opts.requestType) {\n try {\n transport.sendMessage(opts.requestType);\n } catch {\n /* transport not ready — a proactive push will still arrive */\n }\n }\n };\n\n const get = (): T => {\n start();\n return current;\n };\n\n const onChange = (listener: (value: T) => void): (() => void) => {\n start();\n listeners.add(listener);\n listener(current);\n return () => {\n listeners.delete(listener);\n };\n };\n\n const use = (): T => {\n const [value, setValue] = useState<T>(get);\n useEffect(() => onChange(setValue), []);\n return value;\n };\n\n return { get, onChange, use };\n}\n"],"mappings":"AAWA,SAAS,WAAW,gBAAgB;AACpC,SAAS,eAAe,aAAa,eAAe,0BAA0B;AAiBvE,SAAS,kBACd,MAUA,YAA8B,EAAE,aAAa,aAAa,aAAa,mBAAmB,GAC1E;AAChB,MAAI,UAAU,KAAK;AACnB,QAAM,YAAY,oBAAI,IAAwB;AAC9C,MAAI,UAAU;AAKd,QAAM,QAAQ,MAAM;AAClB,QAAI,QAAS;AACb,cAAU;AACV,cAAU,YAAY,KAAK,UAAU,CAAC,QAAQ;AAC5C,YAAM,OAAO,KAAK,MAAM,GAAG;AAC3B,UAAI,SAAS,QAAW;AACtB,kBAAU;AACV,kBAAU,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC;AAAA,MACrC;AAAA,IACF,CAAC;AACD,QAAI,KAAK,aAAa;AACpB,UAAI;AACF,kBAAU,YAAY,KAAK,WAAW;AAAA,MACxC,QAAQ;AAAA,MAER;AAAA,IACF;AAAA,EACF;AAEA,QAAM,MAAM,MAAS;AACnB,UAAM;AACN,WAAO;AAAA,EACT;AAEA,QAAM,WAAW,CAAC,aAA+C;AAC/D,UAAM;AACN,cAAU,IAAI,QAAQ;AACtB,aAAS,OAAO;AAChB,WAAO,MAAM;AACX,gBAAU,OAAO,QAAQ;AAAA,IAC3B;AAAA,EACF;AAEA,QAAM,MAAM,MAAS;AACnB,UAAM,CAAC,OAAO,QAAQ,IAAI,SAAY,GAAG;AACzC,cAAU,MAAM,SAAS,QAAQ,GAAG,CAAC,CAAC;AACtC,WAAO;AAAA,EACT;AAEA,SAAO,EAAE,KAAK,UAAU,IAAI;AAC9B;","names":[]}
|
package/dist/runtime.cjs
CHANGED
|
@@ -21,20 +21,14 @@ __export(runtime_exports, {
|
|
|
21
21
|
SDK_PROTOCOL_VERSION: () => SDK_PROTOCOL_VERSION,
|
|
22
22
|
SDK_VERSION: () => SDK_VERSION,
|
|
23
23
|
announceHandshake: () => announceHandshake,
|
|
24
|
-
getHostRuntime: () => getHostRuntime,
|
|
24
|
+
getHostRuntime: () => import_hostRuntime.getHostRuntime,
|
|
25
25
|
sdkHandshake: () => sdkHandshake
|
|
26
26
|
});
|
|
27
27
|
module.exports = __toCommonJS(runtime_exports);
|
|
28
28
|
var import_sandboxUtils = require("./sandboxUtils");
|
|
29
|
+
var import_hostRuntime = require("./hostRuntime");
|
|
29
30
|
const SDK_PROTOCOL_VERSION = "1.0.0";
|
|
30
|
-
const SDK_VERSION = "0.
|
|
31
|
-
function getHostRuntime() {
|
|
32
|
-
try {
|
|
33
|
-
return globalThis.__immediatelyRun__ ?? null;
|
|
34
|
-
} catch {
|
|
35
|
-
return null;
|
|
36
|
-
}
|
|
37
|
-
}
|
|
31
|
+
const SDK_VERSION = "0.3.0";
|
|
38
32
|
const sdkHandshake = () => ({
|
|
39
33
|
sdkVersion: SDK_VERSION,
|
|
40
34
|
protocolVersion: SDK_PROTOCOL_VERSION
|
package/dist/runtime.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/runtime.ts"],"sourcesContent":["// Runtime discovery + version handshake (SDK_PACKAGING_SPEC §4/§6).\n//\n// Today the SDK reaches the host through the INJECTED sandbox services\n// (`module.evaluation.module.bundler.*`, see sandboxUtils). The packaging migration\n// makes the SDK an app-pinnable npm dependency that finds the runtime through a\n// stable, versioned global the sandbox publishes BEFORE evaluating app code:\n//\n// globalThis.__immediatelyRun__ = { runtimeVersion, protocolVersion, transport }\n//\n// Phase 1 (behind a flag, injection still active): the SDK can READ that global\n// when present (else fall back to injection), and ANNOUNCE its own version +\n// protocol so the host can record + version-check it (§6/T45). The transport itself\n// is unchanged here — this only wires the discovery + handshake fields so the check\n// exists when app-pinned versions become real.\nimport { sendMessage, addListener } from './sandboxUtils';\n\n/** The wire protocol (postMessage envelope / channels / methods) THIS SDK speaks.\n * Additive-only (§9); bump only for a backwards-compatible extension. */\nexport const SDK_PROTOCOL_VERSION = '1.0.0';\n\n/** This SDK's package version. Kept in step with package.json (a build step can\n * inject it later; a constant is fine while versions are still effectively fixed). */\nexport const SDK_VERSION = '0.
|
|
1
|
+
{"version":3,"sources":["../src/runtime.ts"],"sourcesContent":["// Runtime discovery + version handshake (SDK_PACKAGING_SPEC §4/§6).\n//\n// Today the SDK reaches the host through the INJECTED sandbox services\n// (`module.evaluation.module.bundler.*`, see sandboxUtils). The packaging migration\n// makes the SDK an app-pinnable npm dependency that finds the runtime through a\n// stable, versioned global the sandbox publishes BEFORE evaluating app code:\n//\n// globalThis.__immediatelyRun__ = { runtimeVersion, protocolVersion, transport }\n//\n// Phase 1 (behind a flag, injection still active): the SDK can READ that global\n// when present (else fall back to injection), and ANNOUNCE its own version +\n// protocol so the host can record + version-check it (§6/T45). The transport itself\n// is unchanged here — this only wires the discovery + handshake fields so the check\n// exists when app-pinned versions become real.\nimport { sendMessage, addListener } from './sandboxUtils';\n\n// `getHostRuntime` + `ImmediatelyRunGlobal` live in the leaf `hostRuntime` module\n// (imports nothing) and are re-exported here for a stable public API. This breaks\n// the sandboxUtils↔runtime import cycle: sandboxUtils reads `getHostRuntime` from\n// the leaf, while runtime still imports sandboxUtils for the handshake — one\n// direction only, no cycle.\nexport { getHostRuntime } from './hostRuntime';\nexport type { ImmediatelyRunGlobal } from './hostRuntime';\n\n/** The wire protocol (postMessage envelope / channels / methods) THIS SDK speaks.\n * Additive-only (§9); bump only for a backwards-compatible extension. */\nexport const SDK_PROTOCOL_VERSION = '1.0.0';\n\n/** This SDK's package version. Kept in step with package.json (a build step can\n * inject it later; a constant is fine while versions are still effectively fixed). */\nexport const SDK_VERSION = '0.3.0';\n\n/** This SDK's handshake payload — the version + protocol the host records + checks\n * against `HOST_PROTOCOL_VERSION` (§6/T45). */\nexport interface SdkHandshake {\n sdkVersion: string;\n protocolVersion: string;\n}\nexport const sdkHandshake = (): SdkHandshake => ({\n sdkVersion: SDK_VERSION,\n protocolVersion: SDK_PROTOCOL_VERSION,\n});\n\n/**\n * Announce this SDK's version to the host (§6). Sends `sdk-handshake` eagerly\n * (best-effort — the host may already be listening) AND replies to a host\n * `request-handshake` (the robust path, mirroring the other `request-*` pulls).\n * Idempotent; safe to call more than once. Returns an unsubscribe fn.\n */\nexport function announceHandshake(): () => void {\n const send = () => {\n try {\n sendMessage('sdk-handshake', sdkHandshake() as unknown as Record<string, unknown>);\n } catch {\n /* transport not ready yet — the request-handshake reply covers it */\n }\n };\n send();\n return addListener('request-handshake', send);\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAcA,0BAAyC;AAOzC,yBAA+B;AAKxB,MAAM,uBAAuB;AAI7B,MAAM,cAAc;AAQpB,MAAM,eAAe,OAAqB;AAAA,EAC/C,YAAY;AAAA,EACZ,iBAAiB;AACnB;AAQO,SAAS,oBAAgC;AAC9C,QAAM,OAAO,MAAM;AACjB,QAAI;AACF,2CAAY,iBAAiB,aAAa,CAAuC;AAAA,IACnF,QAAQ;AAAA,IAER;AAAA,EACF;AACA,OAAK;AACL,aAAO,iCAAY,qBAAqB,IAAI;AAC9C;","names":[]}
|
package/dist/runtime.d.cts
CHANGED
|
@@ -1,26 +1,11 @@
|
|
|
1
|
+
export { ImmediatelyRunGlobal, getHostRuntime } from './hostRuntime.cjs';
|
|
2
|
+
|
|
1
3
|
/** The wire protocol (postMessage envelope / channels / methods) THIS SDK speaks.
|
|
2
4
|
* Additive-only (§9); bump only for a backwards-compatible extension. */
|
|
3
5
|
declare const SDK_PROTOCOL_VERSION = "1.0.0";
|
|
4
6
|
/** This SDK's package version. Kept in step with package.json (a build step can
|
|
5
7
|
* inject it later; a constant is fine while versions are still effectively fixed). */
|
|
6
|
-
declare const SDK_VERSION = "0.
|
|
7
|
-
/** The sandbox runtime's pre-evaluation discovery global (§4). */
|
|
8
|
-
interface ImmediatelyRunGlobal {
|
|
9
|
-
/** Sandbox-runtime protocol version (semver). */
|
|
10
|
-
runtimeVersion?: string;
|
|
11
|
-
/** postMessage envelope/protocol version. */
|
|
12
|
-
protocolVersion?: string;
|
|
13
|
-
/** The host channel the SDK talks over (MessagePort | message bus). */
|
|
14
|
-
transport?: unknown;
|
|
15
|
-
/** Resolves when ports arrive, if they arrive async after register-frame. */
|
|
16
|
-
ready?: Promise<void>;
|
|
17
|
-
}
|
|
18
|
-
/**
|
|
19
|
-
* Read the sandbox runtime's discovery global (§4), or null when absent — in which
|
|
20
|
-
* case the SDK uses the current INJECTED path (`module.evaluation.*`). Lets the SDK
|
|
21
|
-
* detect a host too old/new and fail closed (§6) once the global ships.
|
|
22
|
-
*/
|
|
23
|
-
declare function getHostRuntime(): ImmediatelyRunGlobal | null;
|
|
8
|
+
declare const SDK_VERSION = "0.3.0";
|
|
24
9
|
/** This SDK's handshake payload — the version + protocol the host records + checks
|
|
25
10
|
* against `HOST_PROTOCOL_VERSION` (§6/T45). */
|
|
26
11
|
interface SdkHandshake {
|
|
@@ -36,4 +21,4 @@ declare const sdkHandshake: () => SdkHandshake;
|
|
|
36
21
|
*/
|
|
37
22
|
declare function announceHandshake(): () => void;
|
|
38
23
|
|
|
39
|
-
export {
|
|
24
|
+
export { SDK_PROTOCOL_VERSION, SDK_VERSION, type SdkHandshake, announceHandshake, sdkHandshake };
|
package/dist/runtime.d.ts
CHANGED
|
@@ -1,26 +1,11 @@
|
|
|
1
|
+
export { ImmediatelyRunGlobal, getHostRuntime } from './hostRuntime.js';
|
|
2
|
+
|
|
1
3
|
/** The wire protocol (postMessage envelope / channels / methods) THIS SDK speaks.
|
|
2
4
|
* Additive-only (§9); bump only for a backwards-compatible extension. */
|
|
3
5
|
declare const SDK_PROTOCOL_VERSION = "1.0.0";
|
|
4
6
|
/** This SDK's package version. Kept in step with package.json (a build step can
|
|
5
7
|
* inject it later; a constant is fine while versions are still effectively fixed). */
|
|
6
|
-
declare const SDK_VERSION = "0.
|
|
7
|
-
/** The sandbox runtime's pre-evaluation discovery global (§4). */
|
|
8
|
-
interface ImmediatelyRunGlobal {
|
|
9
|
-
/** Sandbox-runtime protocol version (semver). */
|
|
10
|
-
runtimeVersion?: string;
|
|
11
|
-
/** postMessage envelope/protocol version. */
|
|
12
|
-
protocolVersion?: string;
|
|
13
|
-
/** The host channel the SDK talks over (MessagePort | message bus). */
|
|
14
|
-
transport?: unknown;
|
|
15
|
-
/** Resolves when ports arrive, if they arrive async after register-frame. */
|
|
16
|
-
ready?: Promise<void>;
|
|
17
|
-
}
|
|
18
|
-
/**
|
|
19
|
-
* Read the sandbox runtime's discovery global (§4), or null when absent — in which
|
|
20
|
-
* case the SDK uses the current INJECTED path (`module.evaluation.*`). Lets the SDK
|
|
21
|
-
* detect a host too old/new and fail closed (§6) once the global ships.
|
|
22
|
-
*/
|
|
23
|
-
declare function getHostRuntime(): ImmediatelyRunGlobal | null;
|
|
8
|
+
declare const SDK_VERSION = "0.3.0";
|
|
24
9
|
/** This SDK's handshake payload — the version + protocol the host records + checks
|
|
25
10
|
* against `HOST_PROTOCOL_VERSION` (§6/T45). */
|
|
26
11
|
interface SdkHandshake {
|
|
@@ -36,4 +21,4 @@ declare const sdkHandshake: () => SdkHandshake;
|
|
|
36
21
|
*/
|
|
37
22
|
declare function announceHandshake(): () => void;
|
|
38
23
|
|
|
39
|
-
export {
|
|
24
|
+
export { SDK_PROTOCOL_VERSION, SDK_VERSION, type SdkHandshake, announceHandshake, sdkHandshake };
|
package/dist/runtime.js
CHANGED
|
@@ -1,13 +1,7 @@
|
|
|
1
1
|
import { sendMessage, addListener } from "./sandboxUtils";
|
|
2
|
+
import { getHostRuntime } from "./hostRuntime";
|
|
2
3
|
const SDK_PROTOCOL_VERSION = "1.0.0";
|
|
3
|
-
const SDK_VERSION = "0.
|
|
4
|
-
function getHostRuntime() {
|
|
5
|
-
try {
|
|
6
|
-
return globalThis.__immediatelyRun__ ?? null;
|
|
7
|
-
} catch {
|
|
8
|
-
return null;
|
|
9
|
-
}
|
|
10
|
-
}
|
|
4
|
+
const SDK_VERSION = "0.3.0";
|
|
11
5
|
const sdkHandshake = () => ({
|
|
12
6
|
sdkVersion: SDK_VERSION,
|
|
13
7
|
protocolVersion: SDK_PROTOCOL_VERSION
|
package/dist/runtime.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/runtime.ts"],"sourcesContent":["// Runtime discovery + version handshake (SDK_PACKAGING_SPEC §4/§6).\n//\n// Today the SDK reaches the host through the INJECTED sandbox services\n// (`module.evaluation.module.bundler.*`, see sandboxUtils). The packaging migration\n// makes the SDK an app-pinnable npm dependency that finds the runtime through a\n// stable, versioned global the sandbox publishes BEFORE evaluating app code:\n//\n// globalThis.__immediatelyRun__ = { runtimeVersion, protocolVersion, transport }\n//\n// Phase 1 (behind a flag, injection still active): the SDK can READ that global\n// when present (else fall back to injection), and ANNOUNCE its own version +\n// protocol so the host can record + version-check it (§6/T45). The transport itself\n// is unchanged here — this only wires the discovery + handshake fields so the check\n// exists when app-pinned versions become real.\nimport { sendMessage, addListener } from './sandboxUtils';\n\n/** The wire protocol (postMessage envelope / channels / methods) THIS SDK speaks.\n * Additive-only (§9); bump only for a backwards-compatible extension. */\nexport const SDK_PROTOCOL_VERSION = '1.0.0';\n\n/** This SDK's package version. Kept in step with package.json (a build step can\n * inject it later; a constant is fine while versions are still effectively fixed). */\nexport const SDK_VERSION = '0.
|
|
1
|
+
{"version":3,"sources":["../src/runtime.ts"],"sourcesContent":["// Runtime discovery + version handshake (SDK_PACKAGING_SPEC §4/§6).\n//\n// Today the SDK reaches the host through the INJECTED sandbox services\n// (`module.evaluation.module.bundler.*`, see sandboxUtils). The packaging migration\n// makes the SDK an app-pinnable npm dependency that finds the runtime through a\n// stable, versioned global the sandbox publishes BEFORE evaluating app code:\n//\n// globalThis.__immediatelyRun__ = { runtimeVersion, protocolVersion, transport }\n//\n// Phase 1 (behind a flag, injection still active): the SDK can READ that global\n// when present (else fall back to injection), and ANNOUNCE its own version +\n// protocol so the host can record + version-check it (§6/T45). The transport itself\n// is unchanged here — this only wires the discovery + handshake fields so the check\n// exists when app-pinned versions become real.\nimport { sendMessage, addListener } from './sandboxUtils';\n\n// `getHostRuntime` + `ImmediatelyRunGlobal` live in the leaf `hostRuntime` module\n// (imports nothing) and are re-exported here for a stable public API. This breaks\n// the sandboxUtils↔runtime import cycle: sandboxUtils reads `getHostRuntime` from\n// the leaf, while runtime still imports sandboxUtils for the handshake — one\n// direction only, no cycle.\nexport { getHostRuntime } from './hostRuntime';\nexport type { ImmediatelyRunGlobal } from './hostRuntime';\n\n/** The wire protocol (postMessage envelope / channels / methods) THIS SDK speaks.\n * Additive-only (§9); bump only for a backwards-compatible extension. */\nexport const SDK_PROTOCOL_VERSION = '1.0.0';\n\n/** This SDK's package version. Kept in step with package.json (a build step can\n * inject it later; a constant is fine while versions are still effectively fixed). */\nexport const SDK_VERSION = '0.3.0';\n\n/** This SDK's handshake payload — the version + protocol the host records + checks\n * against `HOST_PROTOCOL_VERSION` (§6/T45). */\nexport interface SdkHandshake {\n sdkVersion: string;\n protocolVersion: string;\n}\nexport const sdkHandshake = (): SdkHandshake => ({\n sdkVersion: SDK_VERSION,\n protocolVersion: SDK_PROTOCOL_VERSION,\n});\n\n/**\n * Announce this SDK's version to the host (§6). Sends `sdk-handshake` eagerly\n * (best-effort — the host may already be listening) AND replies to a host\n * `request-handshake` (the robust path, mirroring the other `request-*` pulls).\n * Idempotent; safe to call more than once. Returns an unsubscribe fn.\n */\nexport function announceHandshake(): () => void {\n const send = () => {\n try {\n sendMessage('sdk-handshake', sdkHandshake() as unknown as Record<string, unknown>);\n } catch {\n /* transport not ready yet — the request-handshake reply covers it */\n }\n };\n send();\n return addListener('request-handshake', send);\n}\n"],"mappings":"AAcA,SAAS,aAAa,mBAAmB;AAOzC,SAAS,sBAAsB;AAKxB,MAAM,uBAAuB;AAI7B,MAAM,cAAc;AAQpB,MAAM,eAAe,OAAqB;AAAA,EAC/C,YAAY;AAAA,EACZ,iBAAiB;AACnB;AAQO,SAAS,oBAAgC;AAC9C,QAAM,OAAO,MAAM;AACjB,QAAI;AACF,kBAAY,iBAAiB,aAAa,CAAuC;AAAA,IACnF,QAAQ;AAAA,IAER;AAAA,EACF;AACA,OAAK;AACL,SAAO,YAAY,qBAAqB,IAAI;AAC9C;","names":[]}
|
package/dist/sandboxUtils.cjs
CHANGED
|
@@ -23,14 +23,14 @@ __export(sandboxUtils_exports, {
|
|
|
23
23
|
sendMessage: () => sendMessage
|
|
24
24
|
});
|
|
25
25
|
module.exports = __toCommonJS(sandboxUtils_exports);
|
|
26
|
-
var
|
|
26
|
+
var import_hostRuntime = require("./hostRuntime");
|
|
27
27
|
function transport() {
|
|
28
28
|
try {
|
|
29
29
|
const injected = module?.evaluation?.module?.bundler?.messageBus;
|
|
30
30
|
if (injected && typeof injected.sendMessage === "function") return injected;
|
|
31
31
|
} catch {
|
|
32
32
|
}
|
|
33
|
-
const t = (0,
|
|
33
|
+
const t = (0, import_hostRuntime.getHostRuntime)()?.transport;
|
|
34
34
|
if (t && typeof t.sendMessage === "function") return t;
|
|
35
35
|
throw new Error("immediately.run: no host transport (neither injected nor __immediatelyRun__)");
|
|
36
36
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/sandboxUtils.ts"],"sourcesContent":["// Host transport access (SDK_PACKAGING_SPEC §4, expose-transport). All host comms\n// (sendMessage / protocolRequest / onMessage) go through ONE resolver so the SDK is\n// transport-agnostic: it works whether it was INJECTED into the bundler's evaluation\n// context (the current path — `module.evaluation.module.bundler.messageBus`) OR\n// fetched from npm as an ordinary dependency, in which case the sandbox runtime hands\n// it the transport via the §4 discovery global (`globalThis.__immediatelyRun__`).\n//\n// Dual-mode (§8): injection wins while it's active, so existing behaviour is\n// byte-for-byte preserved; the global is the fallback the npm-fetched SDK uses. When\n// injection is removed (phase 3), only the global path remains — `bundler.*` stops\n// being API, which is the whole point.\nimport { getHostRuntime } from './
|
|
1
|
+
{"version":3,"sources":["../src/sandboxUtils.ts"],"sourcesContent":["// Host transport access (SDK_PACKAGING_SPEC §4, expose-transport). All host comms\n// (sendMessage / protocolRequest / onMessage) go through ONE resolver so the SDK is\n// transport-agnostic: it works whether it was INJECTED into the bundler's evaluation\n// context (the current path — `module.evaluation.module.bundler.messageBus`) OR\n// fetched from npm as an ordinary dependency, in which case the sandbox runtime hands\n// it the transport via the §4 discovery global (`globalThis.__immediatelyRun__`).\n//\n// Dual-mode (§8): injection wins while it's active, so existing behaviour is\n// byte-for-byte preserved; the global is the fallback the npm-fetched SDK uses. When\n// injection is removed (phase 3), only the global path remains — `bundler.*` stops\n// being API, which is the whole point.\nimport { getHostRuntime } from './hostRuntime';\n\ninterface HostTransport {\n sendMessage(type: string, data?: Record<string, any>): void;\n protocolRequest(protocolName: string, method: string, params: Array<any>): Promise<any>;\n onMessage(handler: (msg: any) => void): { dispose(): void };\n}\n\nfunction transport(): HostTransport {\n // Injected bundler messageBus first — the current path, unchanged.\n try {\n // @ts-ignore - `module.evaluation` is injected by the sandbox runtime\n const injected = module?.evaluation?.module?.bundler?.messageBus;\n if (injected && typeof injected.sendMessage === 'function') return injected;\n } catch {\n /* no injection in this realm — fall through to the §4 global */\n }\n // §4 runtime-discovery transport (the npm-fetched SDK path).\n const t = getHostRuntime()?.transport as HostTransport | undefined;\n if (t && typeof t.sendMessage === 'function') return t;\n throw new Error('immediately.run: no host transport (neither injected nor __immediatelyRun__)');\n}\n\nexport const sendMessage = (type: string, data: Record<string, any> = {}) => {\n transport().sendMessage(type, data);\n};\n\nexport const protocolRequest = (\n protocolName: string,\n method: string,\n params: Array<any>,\n): Promise<any> => transport().protocolRequest(protocolName, method, params);\n\nexport const addListener = (\n msgType: string,\n handler: (msg: any) => void,\n event?: any,\n): (() => void) => {\n const onMessage = event ?? transport().onMessage;\n const disposable = onMessage((msg: any) => {\n if (msg.type === msgType) {\n handler(msg);\n }\n });\n return () => disposable.dispose();\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAWA,yBAA+B;AAQ/B,SAAS,YAA2B;AAElC,MAAI;AAEF,UAAM,WAAW,QAAQ,YAAY,QAAQ,SAAS;AACtD,QAAI,YAAY,OAAO,SAAS,gBAAgB,WAAY,QAAO;AAAA,EACrE,QAAQ;AAAA,EAER;AAEA,QAAM,QAAI,mCAAe,GAAG;AAC5B,MAAI,KAAK,OAAO,EAAE,gBAAgB,WAAY,QAAO;AACrD,QAAM,IAAI,MAAM,8EAA8E;AAChG;AAEO,MAAM,cAAc,CAAC,MAAc,OAA4B,CAAC,MAAM;AAC3E,YAAU,EAAE,YAAY,MAAM,IAAI;AACpC;AAEO,MAAM,kBAAkB,CAC7B,cACA,QACA,WACiB,UAAU,EAAE,gBAAgB,cAAc,QAAQ,MAAM;AAEpE,MAAM,cAAc,CACzB,SACA,SACA,UACiB;AACjB,QAAM,YAAY,SAAS,UAAU,EAAE;AACvC,QAAM,aAAa,UAAU,CAAC,QAAa;AACzC,QAAI,IAAI,SAAS,SAAS;AACxB,cAAQ,GAAG;AAAA,IACb;AAAA,EACF,CAAC;AACD,SAAO,MAAM,WAAW,QAAQ;AAClC;","names":[]}
|
package/dist/sandboxUtils.js
CHANGED
package/dist/sandboxUtils.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/sandboxUtils.ts"],"sourcesContent":["// Host transport access (SDK_PACKAGING_SPEC §4, expose-transport). All host comms\n// (sendMessage / protocolRequest / onMessage) go through ONE resolver so the SDK is\n// transport-agnostic: it works whether it was INJECTED into the bundler's evaluation\n// context (the current path — `module.evaluation.module.bundler.messageBus`) OR\n// fetched from npm as an ordinary dependency, in which case the sandbox runtime hands\n// it the transport via the §4 discovery global (`globalThis.__immediatelyRun__`).\n//\n// Dual-mode (§8): injection wins while it's active, so existing behaviour is\n// byte-for-byte preserved; the global is the fallback the npm-fetched SDK uses. When\n// injection is removed (phase 3), only the global path remains — `bundler.*` stops\n// being API, which is the whole point.\nimport { getHostRuntime } from './
|
|
1
|
+
{"version":3,"sources":["../src/sandboxUtils.ts"],"sourcesContent":["// Host transport access (SDK_PACKAGING_SPEC §4, expose-transport). All host comms\n// (sendMessage / protocolRequest / onMessage) go through ONE resolver so the SDK is\n// transport-agnostic: it works whether it was INJECTED into the bundler's evaluation\n// context (the current path — `module.evaluation.module.bundler.messageBus`) OR\n// fetched from npm as an ordinary dependency, in which case the sandbox runtime hands\n// it the transport via the §4 discovery global (`globalThis.__immediatelyRun__`).\n//\n// Dual-mode (§8): injection wins while it's active, so existing behaviour is\n// byte-for-byte preserved; the global is the fallback the npm-fetched SDK uses. When\n// injection is removed (phase 3), only the global path remains — `bundler.*` stops\n// being API, which is the whole point.\nimport { getHostRuntime } from './hostRuntime';\n\ninterface HostTransport {\n sendMessage(type: string, data?: Record<string, any>): void;\n protocolRequest(protocolName: string, method: string, params: Array<any>): Promise<any>;\n onMessage(handler: (msg: any) => void): { dispose(): void };\n}\n\nfunction transport(): HostTransport {\n // Injected bundler messageBus first — the current path, unchanged.\n try {\n // @ts-ignore - `module.evaluation` is injected by the sandbox runtime\n const injected = module?.evaluation?.module?.bundler?.messageBus;\n if (injected && typeof injected.sendMessage === 'function') return injected;\n } catch {\n /* no injection in this realm — fall through to the §4 global */\n }\n // §4 runtime-discovery transport (the npm-fetched SDK path).\n const t = getHostRuntime()?.transport as HostTransport | undefined;\n if (t && typeof t.sendMessage === 'function') return t;\n throw new Error('immediately.run: no host transport (neither injected nor __immediatelyRun__)');\n}\n\nexport const sendMessage = (type: string, data: Record<string, any> = {}) => {\n transport().sendMessage(type, data);\n};\n\nexport const protocolRequest = (\n protocolName: string,\n method: string,\n params: Array<any>,\n): Promise<any> => transport().protocolRequest(protocolName, method, params);\n\nexport const addListener = (\n msgType: string,\n handler: (msg: any) => void,\n event?: any,\n): (() => void) => {\n const onMessage = event ?? transport().onMessage;\n const disposable = onMessage((msg: any) => {\n if (msg.type === msgType) {\n handler(msg);\n }\n });\n return () => disposable.dispose();\n};\n"],"mappings":"AAWA,SAAS,sBAAsB;AAQ/B,SAAS,YAA2B;AAElC,MAAI;AAEF,UAAM,WAAW,QAAQ,YAAY,QAAQ,SAAS;AACtD,QAAI,YAAY,OAAO,SAAS,gBAAgB,WAAY,QAAO;AAAA,EACrE,QAAQ;AAAA,EAER;AAEA,QAAM,IAAI,eAAe,GAAG;AAC5B,MAAI,KAAK,OAAO,EAAE,gBAAgB,WAAY,QAAO;AACrD,QAAM,IAAI,MAAM,8EAA8E;AAChG;AAEO,MAAM,cAAc,CAAC,MAAc,OAA4B,CAAC,MAAM;AAC3E,YAAU,EAAE,YAAY,MAAM,IAAI;AACpC;AAEO,MAAM,kBAAkB,CAC7B,cACA,QACA,WACiB,UAAU,EAAE,gBAAgB,cAAc,QAAQ,MAAM;AAEpE,MAAM,cAAc,CACzB,SACA,SACA,UACiB;AACjB,QAAM,YAAY,SAAS,UAAU,EAAE;AACvC,QAAM,aAAa,UAAU,CAAC,QAAa;AACzC,QAAI,IAAI,SAAS,SAAS;AACxB,cAAQ,GAAG;AAAA,IACb;AAAA,EACF,CAAC;AACD,SAAO,MAAM,WAAW,QAAQ;AAClC;","names":[]}
|
package/dist/theme.cjs
CHANGED
|
@@ -24,21 +24,17 @@ __export(theme_exports, {
|
|
|
24
24
|
useHostTheme: () => useHostTheme
|
|
25
25
|
});
|
|
26
26
|
module.exports = __toCommonJS(theme_exports);
|
|
27
|
-
var
|
|
27
|
+
var import_pushChannel = require("./pushChannel");
|
|
28
28
|
var import_sandboxUtils = require("./sandboxUtils");
|
|
29
|
-
const
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
const useHostTheme = () =>
|
|
38
|
-
const [theme, setTheme] = (0, import_react.useState)(getHostTheme);
|
|
39
|
-
(0, import_react.useEffect)(() => onHostThemeChange(setTheme), []);
|
|
40
|
-
return theme;
|
|
41
|
-
};
|
|
29
|
+
const channel = (0, import_pushChannel.createPushChannel)({
|
|
30
|
+
pushType: "theme",
|
|
31
|
+
requestType: "request-theme",
|
|
32
|
+
initial: "dark",
|
|
33
|
+
parse: (msg) => msg.theme === "light" || msg.theme === "dark" ? msg.theme : void 0
|
|
34
|
+
});
|
|
35
|
+
const getHostTheme = () => channel.get();
|
|
36
|
+
const onHostThemeChange = (listener) => channel.onChange(listener);
|
|
37
|
+
const useHostTheme = () => channel.use();
|
|
42
38
|
const setHostTheme = async (theme) => {
|
|
43
39
|
const res = await (0, import_sandboxUtils.protocolRequest)("theme", "set", [{ theme }]);
|
|
44
40
|
if (!res || res.ok !== true) {
|
package/dist/theme.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/theme.ts"],"sourcesContent":["import {
|
|
1
|
+
{"version":3,"sources":["../src/theme.ts"],"sourcesContent":["import { createPushChannel } from './pushChannel';\nimport { protocolRequest } from './sandboxUtils';\n\n/**\n * The host UI theme, mirrored from the immediately.run host window into the\n * sandbox. Your app can read this to render in step with the host chrome\n * (light / dark).\n *\n * This is the baseline `theme:read` capability — every app may read it. Changing\n * the host theme is a separate, elevated action (`theme:set`), available only to\n * the theme-toggle system app.\n */\nexport type HostTheme = 'light' | 'dark';\n\n// Read over the transport (SDK_PACKAGING_SPEC §4): the host pushes `theme` and\n// answers `request-theme` (wire format: site-main channelBridge.ts). The host's\n// default before it reports is `dark` (sandbox themeState.DEFAULT_THEME).\nconst channel = createPushChannel<HostTheme>({\n pushType: 'theme',\n requestType: 'request-theme',\n initial: 'dark',\n parse: (msg) => (msg.theme === 'light' || msg.theme === 'dark' ? msg.theme : undefined),\n});\n\n/**\n * Returns the current host theme. Poll this for a one-off read; use\n * {@link onHostThemeChange} or {@link useHostTheme} to react to changes.\n */\nexport const getHostTheme = (): HostTheme => channel.get();\n\n/**\n * Subscribe to host theme changes. The listener is invoked immediately with the\n * current theme, then again on every change. Returns an unsubscribe fn.\n */\nexport const onHostThemeChange = (listener: (theme: HostTheme) => void): (() => void) =>\n channel.onChange(listener);\n\n/**\n * React hook returning the current host theme, re-rendering when it changes.\n * The recommended way to implement an app's own `useTheme`: follow the host,\n * allow a local override.\n */\nexport const useHostTheme = (): HostTheme => channel.use();\n\n/**\n * Set the host UI theme — the ELEVATED `theme:set` action (§8.5). The host\n * applies it and re-pushes the new value to every `theme:read` iframe, so your\n * own {@link useHostTheme} confirms the change (the loop closes with no special\n * case). Only a grant holding `theme:set` (e.g. the theme-toggle system app) may\n * call this; any other app is rejected host-side with a `forbidden`\n * {@link Error} (carrying `.code`), regardless of what the app claims. Update\n * optimistically and let the re-push confirm.\n */\nexport const setHostTheme = async (theme: HostTheme): Promise<void> => {\n const res = (await protocolRequest('theme', 'set', [{ theme }])) as\n | { ok: true; data?: unknown }\n | { ok: false; code?: string; message?: string }\n | undefined;\n if (!res || res.ok !== true) {\n const err = new Error(res?.message ?? 'setHostTheme failed') as Error & {\n code?: string;\n };\n err.code = (res && 'code' in res ? res.code : undefined) ?? 'unknown';\n throw err;\n }\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,yBAAkC;AAClC,0BAAgC;AAgBhC,MAAM,cAAU,sCAA6B;AAAA,EAC3C,UAAU;AAAA,EACV,aAAa;AAAA,EACb,SAAS;AAAA,EACT,OAAO,CAAC,QAAS,IAAI,UAAU,WAAW,IAAI,UAAU,SAAS,IAAI,QAAQ;AAC/E,CAAC;AAMM,MAAM,eAAe,MAAiB,QAAQ,IAAI;AAMlD,MAAM,oBAAoB,CAAC,aAChC,QAAQ,SAAS,QAAQ;AAOpB,MAAM,eAAe,MAAiB,QAAQ,IAAI;AAWlD,MAAM,eAAe,OAAO,UAAoC;AACrE,QAAM,MAAO,UAAM,qCAAgB,SAAS,OAAO,CAAC,EAAE,MAAM,CAAC,CAAC;AAI9D,MAAI,CAAC,OAAO,IAAI,OAAO,MAAM;AAC3B,UAAM,MAAM,IAAI,MAAM,KAAK,WAAW,qBAAqB;AAG3D,QAAI,QAAQ,OAAO,UAAU,MAAM,IAAI,OAAO,WAAc;AAC5D,UAAM;AAAA,EACR;AACF;","names":[]}
|
package/dist/theme.js
CHANGED
|
@@ -1,18 +1,14 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { createPushChannel } from "./pushChannel";
|
|
2
2
|
import { protocolRequest } from "./sandboxUtils";
|
|
3
|
-
const
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
const useHostTheme = () =>
|
|
12
|
-
const [theme, setTheme] = useState(getHostTheme);
|
|
13
|
-
useEffect(() => onHostThemeChange(setTheme), []);
|
|
14
|
-
return theme;
|
|
15
|
-
};
|
|
3
|
+
const channel = createPushChannel({
|
|
4
|
+
pushType: "theme",
|
|
5
|
+
requestType: "request-theme",
|
|
6
|
+
initial: "dark",
|
|
7
|
+
parse: (msg) => msg.theme === "light" || msg.theme === "dark" ? msg.theme : void 0
|
|
8
|
+
});
|
|
9
|
+
const getHostTheme = () => channel.get();
|
|
10
|
+
const onHostThemeChange = (listener) => channel.onChange(listener);
|
|
11
|
+
const useHostTheme = () => channel.use();
|
|
16
12
|
const setHostTheme = async (theme) => {
|
|
17
13
|
const res = await protocolRequest("theme", "set", [{ theme }]);
|
|
18
14
|
if (!res || res.ok !== true) {
|
package/dist/theme.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/theme.ts"],"sourcesContent":["import {
|
|
1
|
+
{"version":3,"sources":["../src/theme.ts"],"sourcesContent":["import { createPushChannel } from './pushChannel';\nimport { protocolRequest } from './sandboxUtils';\n\n/**\n * The host UI theme, mirrored from the immediately.run host window into the\n * sandbox. Your app can read this to render in step with the host chrome\n * (light / dark).\n *\n * This is the baseline `theme:read` capability — every app may read it. Changing\n * the host theme is a separate, elevated action (`theme:set`), available only to\n * the theme-toggle system app.\n */\nexport type HostTheme = 'light' | 'dark';\n\n// Read over the transport (SDK_PACKAGING_SPEC §4): the host pushes `theme` and\n// answers `request-theme` (wire format: site-main channelBridge.ts). The host's\n// default before it reports is `dark` (sandbox themeState.DEFAULT_THEME).\nconst channel = createPushChannel<HostTheme>({\n pushType: 'theme',\n requestType: 'request-theme',\n initial: 'dark',\n parse: (msg) => (msg.theme === 'light' || msg.theme === 'dark' ? msg.theme : undefined),\n});\n\n/**\n * Returns the current host theme. Poll this for a one-off read; use\n * {@link onHostThemeChange} or {@link useHostTheme} to react to changes.\n */\nexport const getHostTheme = (): HostTheme => channel.get();\n\n/**\n * Subscribe to host theme changes. The listener is invoked immediately with the\n * current theme, then again on every change. Returns an unsubscribe fn.\n */\nexport const onHostThemeChange = (listener: (theme: HostTheme) => void): (() => void) =>\n channel.onChange(listener);\n\n/**\n * React hook returning the current host theme, re-rendering when it changes.\n * The recommended way to implement an app's own `useTheme`: follow the host,\n * allow a local override.\n */\nexport const useHostTheme = (): HostTheme => channel.use();\n\n/**\n * Set the host UI theme — the ELEVATED `theme:set` action (§8.5). The host\n * applies it and re-pushes the new value to every `theme:read` iframe, so your\n * own {@link useHostTheme} confirms the change (the loop closes with no special\n * case). Only a grant holding `theme:set` (e.g. the theme-toggle system app) may\n * call this; any other app is rejected host-side with a `forbidden`\n * {@link Error} (carrying `.code`), regardless of what the app claims. Update\n * optimistically and let the re-push confirm.\n */\nexport const setHostTheme = async (theme: HostTheme): Promise<void> => {\n const res = (await protocolRequest('theme', 'set', [{ theme }])) as\n | { ok: true; data?: unknown }\n | { ok: false; code?: string; message?: string }\n | undefined;\n if (!res || res.ok !== true) {\n const err = new Error(res?.message ?? 'setHostTheme failed') as Error & {\n code?: string;\n };\n err.code = (res && 'code' in res ? res.code : undefined) ?? 'unknown';\n throw err;\n }\n};\n"],"mappings":"AAAA,SAAS,yBAAyB;AAClC,SAAS,uBAAuB;AAgBhC,MAAM,UAAU,kBAA6B;AAAA,EAC3C,UAAU;AAAA,EACV,aAAa;AAAA,EACb,SAAS;AAAA,EACT,OAAO,CAAC,QAAS,IAAI,UAAU,WAAW,IAAI,UAAU,SAAS,IAAI,QAAQ;AAC/E,CAAC;AAMM,MAAM,eAAe,MAAiB,QAAQ,IAAI;AAMlD,MAAM,oBAAoB,CAAC,aAChC,QAAQ,SAAS,QAAQ;AAOpB,MAAM,eAAe,MAAiB,QAAQ,IAAI;AAWlD,MAAM,eAAe,OAAO,UAAoC;AACrE,QAAM,MAAO,MAAM,gBAAgB,SAAS,OAAO,CAAC,EAAE,MAAM,CAAC,CAAC;AAI9D,MAAI,CAAC,OAAO,IAAI,OAAO,MAAM;AAC3B,UAAM,MAAM,IAAI,MAAM,KAAK,WAAW,qBAAqB;AAG3D,QAAI,QAAQ,OAAO,UAAU,MAAM,IAAI,OAAO,WAAc;AAC5D,UAAM;AAAA,EACR;AACF;","names":[]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@immediately-run/sdk",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.0",
|
|
4
4
|
"description": "Runtime SDK for code executing inside an immediately.run sandbox.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": "github:immediately-run/immediately-run-sdk",
|
|
@@ -27,8 +27,11 @@
|
|
|
27
27
|
"scripts": {
|
|
28
28
|
"build": "tsup",
|
|
29
29
|
"test": "jest",
|
|
30
|
+
"check:circular": "node scripts/check-circular.mjs",
|
|
31
|
+
"api:check": "node scripts/check-api-stability.mjs",
|
|
32
|
+
"api:update": "node scripts/check-api-stability.mjs --update",
|
|
30
33
|
"docs": "typedoc",
|
|
31
|
-
"prepublishOnly": "npm run build"
|
|
34
|
+
"prepublishOnly": "npm run check:circular && npm run build && npm run api:check"
|
|
32
35
|
},
|
|
33
36
|
"peerDependencies": {
|
|
34
37
|
"react": "^19.0.0",
|