devframe 0.9.4 → 0.9.6
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/README.md +1 -1
- package/dist/{_shared-BPovvJW8.d.mts → _shared-BJ6AmwTu.d.mts} +1 -1
- package/dist/adapters/build.d.mts +5 -4
- package/dist/adapters/build.mjs +4 -3
- package/dist/adapters/cac.d.mts +1 -1
- package/dist/adapters/cac.mjs +3 -2
- package/dist/adapters/dev.d.mts +12 -11
- package/dist/adapters/dev.mjs +1 -1
- package/dist/adapters/embedded.d.mts +1 -1
- package/dist/adapters/initiate.d.mts +9 -8
- package/dist/adapters/initiate.mjs +1 -1
- package/dist/adapters/mcp.d.mts +30 -26
- package/dist/adapters/mcp.mjs +559 -1
- package/dist/cli/main.mjs +1 -1
- package/dist/client/index.d.mts +5 -5
- package/dist/client/index.mjs +1 -64
- package/dist/constants.d.mts +13 -1
- package/dist/constants.mjs +1 -1
- package/dist/{context-_i51nYOs.d.mts → context-BhBzOXVa.d.mts} +23 -11
- package/dist/{context-CO7eZHJy.d.mts → context-HOnG-WvG.d.mts} +1 -1
- package/dist/{context-BUJGvlje.mjs → context-KUqAfawQ.mjs} +1 -1
- package/dist/{context-CQW0lSw8.mjs → context-omlma_1n.mjs} +3 -150
- package/dist/{dev-lpIvwagf.mjs → dev-Czit5IP4.mjs} +6 -5
- package/dist/{events-DKfSmoTj.mjs → events-4daw0uK9.mjs} +16 -2
- package/dist/in-page-channel/index.d.mts +306 -0
- package/dist/in-page-channel/index.mjs +816 -0
- package/dist/{index-DOg4S5wk.d.mts → index-BzyopqxV.d.mts} +1 -1
- package/dist/{index-CEvd-YXD.d.mts → index-DcKxIMoI.d.mts} +2 -2
- package/dist/index.d.mts +14 -6
- package/dist/index.mjs +11 -1
- package/dist/{instance-shell-BHvBIGP4.d.mts → instance-shell-Bh4l9Vz_.d.mts} +3 -3
- package/dist/{instance-shell-B-uevnK-.mjs → instance-shell-CpVW4zG0.mjs} +15 -2
- package/dist/internal/index.d.mts +17 -7
- package/dist/internal/index.mjs +3 -3
- package/dist/node/auth.d.mts +2 -2
- package/dist/node/auth.mjs +1 -1
- package/dist/node/hub-internals.d.mts +2 -2
- package/dist/node/hub-internals.mjs +1 -1
- package/dist/node/index.d.mts +3 -3
- package/dist/node/index.mjs +1 -1
- package/dist/recipes/common-rpc-functions.d.mts +3 -3
- package/dist/recipes/interactive-auth.d.mts +13 -2
- package/dist/recipes/interactive-auth.mjs +5 -1
- package/dist/{remote-assets-Bg4gCUZ_.d.mts → remote-assets-B13_vRkJ.d.mts} +1 -1
- package/dist/{revoke-3Q6aDKWk.mjs → revoke-COLW0cOi.mjs} +1 -1
- package/dist/rpc/dump.d.mts +1 -1
- package/dist/rpc/index.d.mts +2 -2
- package/dist/rpc/transports/sse-client.d.mts +1 -1
- package/dist/rpc/transports/sse-server.d.mts +2 -2
- package/dist/rpc/transports/ws-bun.d.mts +2 -2
- package/dist/rpc/transports/ws-client.d.mts +1 -1
- package/dist/rpc/transports/ws-deno.d.mts +2 -2
- package/dist/rpc/transports/ws-server.d.mts +1 -1
- package/dist/{rpc-core-CDZoGYiD.d.mts → rpc-core-BHUsDl7s.d.mts} +3 -3
- package/dist/{host-agent-B84av916.mjs → services-install-CqqQVls5.mjs} +150 -2
- package/dist/{sse-client-CdGD_B8_.d.mts → sse-client-DwX021ST.d.mts} +1 -1
- package/dist/types/index.d.mts +4 -4
- package/dist/{types-BBLeGfpt.d.mts → types-CMdPYhOx.d.mts} +1 -1
- package/dist/utils/events.d.mts +1 -1
- package/dist/utils/remote-assets.d.mts +1 -1
- package/dist/utils/serve-static.d.mts +1 -1
- package/dist/utils/serve-static.mjs +1 -1
- package/dist/utils/shared-state.d.mts +1 -1
- package/dist/utils/streaming-channel.d.mts +1 -1
- package/dist/{ws-client-Bo2t6hES.d.mts → ws-client-7_lZi-B9.d.mts} +1 -1
- package/dist/{ws-server-DLtEoLdR.d.mts → ws-server-Di2oqr4q.d.mts} +1 -1
- package/package.json +2 -1
- package/skills/devframe/SKILL.md +88 -84
- package/skills/devframe/templates/hub.ts +1 -1
- package/dist/http-BKiqHcXX.mjs +0 -569
- package/dist/transports-vhizgqXM.mjs +0 -15
package/dist/constants.mjs
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { d as RpcFunctionsCollectorBase } from "./index-
|
|
2
|
-
import { _ as RpcFunctionDefinition, v as RpcFunctionDefinitionAny } from "./types-
|
|
3
|
-
import { d as DevframeRpcConnection, u as DevframeNodeRpcSessionMeta } from "./ws-server-
|
|
4
|
-
import { a as RemoteAssetsStore, o as StaticAssetsSource } from "./remote-assets-
|
|
1
|
+
import { d as RpcFunctionsCollectorBase } from "./index-BzyopqxV.mjs";
|
|
2
|
+
import { _ as RpcFunctionDefinition, v as RpcFunctionDefinitionAny } from "./types-CMdPYhOx.mjs";
|
|
3
|
+
import { d as DevframeRpcConnection, u as DevframeNodeRpcSessionMeta } from "./ws-server-Di2oqr4q.mjs";
|
|
4
|
+
import { a as RemoteAssetsStore, o as StaticAssetsSource } from "./remote-assets-B13_vRkJ.mjs";
|
|
5
5
|
import { m as defineDiagnostics } from "./nostics-SPGDgHEP.mjs";
|
|
6
6
|
import { BirpcReturn } from "birpc";
|
|
7
7
|
import { StandardSchemaV1 } from "@standard-schema/spec";
|
|
@@ -444,8 +444,8 @@ interface DevframeHost {
|
|
|
444
444
|
* for cross-origin or sandboxed iframes. Implementations serve the same
|
|
445
445
|
* meta they expose at the hub's own base.
|
|
446
446
|
*
|
|
447
|
-
* Optional in the type, but a host that mounts a devframe with
|
|
448
|
-
* `
|
|
447
|
+
* Optional in the type, but a host that mounts a devframe with servable
|
|
448
|
+
* `clientAssets` yet omits this hook triggers a `DF8106` diagnostic, since the
|
|
449
449
|
* SPA's `./__connection.json` fetch would otherwise fall through and break
|
|
450
450
|
* silently. A static-snapshot host that bakes the meta into its served files
|
|
451
451
|
* can implement it as a no-op to acknowledge this intentionally.
|
|
@@ -1234,10 +1234,11 @@ interface DevframeCliOptions {
|
|
|
1234
1234
|
*/
|
|
1235
1235
|
mcp?: boolean | McpRouteOptions;
|
|
1236
1236
|
/**
|
|
1237
|
-
* Author's SPA dist — served as the devframe's UI.
|
|
1238
|
-
*
|
|
1239
|
-
*
|
|
1240
|
-
*
|
|
1237
|
+
* Author's SPA dist — served as the devframe's UI.
|
|
1238
|
+
*
|
|
1239
|
+
* @deprecated Moved to the top-level {@link DevframeDefinition.clientAssets}.
|
|
1240
|
+
* Set `clientAssets` on the definition instead. This field is still read as a
|
|
1241
|
+
* fallback when `clientAssets` is unset, so existing definitions keep working.
|
|
1241
1242
|
*/
|
|
1242
1243
|
distDir?: StaticAssetsSource;
|
|
1243
1244
|
/**
|
|
@@ -1357,7 +1358,7 @@ interface DevframeDefinition {
|
|
|
1357
1358
|
* consuming app's.
|
|
1358
1359
|
*
|
|
1359
1360
|
* - **Remote assets** — becomes the default `resolveFrom` for any remote
|
|
1360
|
-
* {@link StaticAssetsSource} the devframe hosts (its `
|
|
1361
|
+
* {@link StaticAssetsSource} the devframe hosts (its `clientAssets`, and
|
|
1361
1362
|
* every `ctx.views.hostStatic` call) that doesn't set one explicitly, so a
|
|
1362
1363
|
* locally installed copy of the assets package is served with zero
|
|
1363
1364
|
* network. A per-asset `resolveFrom` still wins, and an explicit
|
|
@@ -1434,6 +1435,17 @@ interface DevframeDefinition {
|
|
|
1434
1435
|
* `client.services.has(pkg)` and degrade.
|
|
1435
1436
|
*/
|
|
1436
1437
|
services?: DevframeServiceInput[];
|
|
1438
|
+
/**
|
|
1439
|
+
* Author's SPA dist — served as the devframe's UI. A local directory, or
|
|
1440
|
+
* a {@link StaticAssetsSource} remote declaration (`{ package, version }`)
|
|
1441
|
+
* served through devframe's caching CDN back-proxy so the assets need not
|
|
1442
|
+
* ship inside the node package.
|
|
1443
|
+
*
|
|
1444
|
+
* Consumed by every adapter that serves the UI (`dev`, `build`, `vite`,
|
|
1445
|
+
* `next`, and the hub install path). When unset, the deprecated
|
|
1446
|
+
* {@link DevframeCliOptions.distDir} is read as a fallback.
|
|
1447
|
+
*/
|
|
1448
|
+
clientAssets?: StaticAssetsSource;
|
|
1437
1449
|
/** RPC-level configuration for this devframe (see {@link DevframeRpcOptions}). */
|
|
1438
1450
|
rpc?: DevframeRpcOptions;
|
|
1439
1451
|
/** Server-side setup — the primary entrypoint. Runs in every runtime. */
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { k as SharedState, o as DevframeNodeContext } from "./context-
|
|
1
|
+
import { k as SharedState, o as DevframeNodeContext } from "./context-BhBzOXVa.mjs";
|
|
2
2
|
//#region src/node/hub-internals/context.d.ts
|
|
3
3
|
interface InternalAnonymousAuthStorage {
|
|
4
4
|
trusted: Record<string, {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { n as randomToken } from "./crypto-token-XCqTSMg9.mjs";
|
|
2
2
|
import { t as createStorage } from "./storage-BXNVhKyR.mjs";
|
|
3
|
-
import { n as revokeAuthToken, t as revokeActiveConnectionsForToken } from "./revoke-
|
|
3
|
+
import { n as revokeAuthToken, t as revokeActiveConnectionsForToken } from "./revoke-COLW0cOi.mjs";
|
|
4
4
|
import { join } from "pathe";
|
|
5
5
|
//#region src/node/hub-internals/context.ts
|
|
6
6
|
const internalContextMap = /* @__PURE__ */ new WeakMap();
|
|
@@ -2,17 +2,15 @@ import { i as defineDiagnostics } from "./nostics-CzECRXpE.mjs";
|
|
|
2
2
|
import { t as diagnostics } from "./diagnostics-CD8nlgll.mjs";
|
|
3
3
|
import { RpcFunctionsCollectorBase } from "./rpc/index.mjs";
|
|
4
4
|
import { defineRpcFunction } from "./index.mjs";
|
|
5
|
-
import { t as DEVFRAME_EVENTS } from "./events-
|
|
5
|
+
import { t as DEVFRAME_EVENTS } from "./events-4daw0uK9.mjs";
|
|
6
6
|
import { DEVFRAME_SERVICES_STATE_KEY } from "./constants.mjs";
|
|
7
7
|
import { t as diagnostics$1 } from "./diagnostics-BXWW3VK-.mjs";
|
|
8
|
-
import { r as createEventEmitter, t as
|
|
8
|
+
import { a as DevframeAgentHost, i as satisfiesVersionRange, n as expandResolveFrom, r as importServicePackage, s as createEventEmitter, t as deepMergeOptionSets } from "./services-install-CqqQVls5.mjs";
|
|
9
9
|
import { n as createDebug, t as resolveStaticAssetsSource } from "./remote-assets-DezQmPQU.mjs";
|
|
10
10
|
import { t as createStorage } from "./storage-BXNVhKyR.mjs";
|
|
11
|
-
import { createRequire } from "node:module";
|
|
12
11
|
import { createSharedState } from "devframe/utils/shared-state";
|
|
13
12
|
import process from "node:process";
|
|
14
|
-
import {
|
|
15
|
-
import { isAbsolute, join } from "pathe";
|
|
13
|
+
import { join } from "pathe";
|
|
16
14
|
import { existsSync } from "node:fs";
|
|
17
15
|
//#region src/node/host-diagnostics.ts
|
|
18
16
|
var DevframeDiagnosticsHost = class {
|
|
@@ -763,151 +761,6 @@ var RpcFunctionsHostImpl = class extends RpcFunctionsCollectorBase {
|
|
|
763
761
|
}
|
|
764
762
|
};
|
|
765
763
|
//#endregion
|
|
766
|
-
//#region src/node/services-install.ts
|
|
767
|
-
/**
|
|
768
|
-
* Turn a `resolveFrom` value (a file path, a file URL like `import.meta.url`,
|
|
769
|
-
* or a directory) into something `createRequire` accepts — a directory gets a
|
|
770
|
-
* synthetic filename appended so resolution starts inside it.
|
|
771
|
-
*/
|
|
772
|
-
function toRequireBase(resolveFrom) {
|
|
773
|
-
if (resolveFrom.startsWith("file://")) return resolveFrom;
|
|
774
|
-
if ((resolveFrom.split(/[/\\]/).pop() ?? "").includes(".")) return resolveFrom;
|
|
775
|
-
return join(resolveFrom, "_devframe_resolve.js");
|
|
776
|
-
}
|
|
777
|
-
/**
|
|
778
|
-
* Normalize an `install()` `resolveFrom` into a resolution base. Paths and
|
|
779
|
-
* file URLs pass through (the common case: the declaring plugin's
|
|
780
|
-
* `importMetaUrl`, so a service it declares resolves against the plugin's own
|
|
781
|
-
* dependencies); a bare npm package name resolves to that package's location
|
|
782
|
-
* from `cwd`. An unresolvable package name reads as no base (the caller's
|
|
783
|
-
* workspace fallbacks apply).
|
|
784
|
-
*/
|
|
785
|
-
function expandResolveFrom(resolveFrom, cwd) {
|
|
786
|
-
if (resolveFrom.startsWith("file://") || resolveFrom.startsWith(".") || isAbsolute(resolveFrom)) return resolveFrom;
|
|
787
|
-
const require = createRequire(join(cwd, "_devframe_resolve.js"));
|
|
788
|
-
try {
|
|
789
|
-
return require.resolve(`${resolveFrom}/package.json`);
|
|
790
|
-
} catch {}
|
|
791
|
-
try {
|
|
792
|
-
return require.resolve(resolveFrom);
|
|
793
|
-
} catch {}
|
|
794
|
-
}
|
|
795
|
-
/**
|
|
796
|
-
* Import a service package's module, trying each `resolveFrom` candidate in
|
|
797
|
-
* order (so a plugin-declared service resolves against the plugin's own
|
|
798
|
-
* dependency tree first, then the workspace fallback). Throws the last
|
|
799
|
-
* resolution error when no candidate succeeds.
|
|
800
|
-
*/
|
|
801
|
-
async function importServicePackage(pkg, resolveFroms) {
|
|
802
|
-
const candidates = [...new Set(resolveFroms.filter((x) => typeof x === "string" && x.length > 0))];
|
|
803
|
-
let lastError = /* @__PURE__ */ new Error(`no resolution base available for "${pkg}"`);
|
|
804
|
-
for (const from of candidates) {
|
|
805
|
-
let resolved;
|
|
806
|
-
try {
|
|
807
|
-
resolved = createRequire(toRequireBase(from)).resolve(pkg);
|
|
808
|
-
} catch (error) {
|
|
809
|
-
lastError = error;
|
|
810
|
-
continue;
|
|
811
|
-
}
|
|
812
|
-
return await import(
|
|
813
|
-
/* webpackIgnore: true */
|
|
814
|
-
/* @vite-ignore */
|
|
815
|
-
/* turbopackIgnore: true */
|
|
816
|
-
pathToFileURL(resolved).href
|
|
817
|
-
);
|
|
818
|
-
}
|
|
819
|
-
throw lastError;
|
|
820
|
-
}
|
|
821
|
-
function parseVersion(input) {
|
|
822
|
-
const [core, ...prerelease] = input.trim().replace(/^v/, "").split("-");
|
|
823
|
-
if (!core) return void 0;
|
|
824
|
-
const parts = core.split(".").map((part) => Number.parseInt(part, 10));
|
|
825
|
-
if (parts.length === 0 || parts.some((part) => Number.isNaN(part) || part < 0)) return void 0;
|
|
826
|
-
while (parts.length < 3) parts.push(0);
|
|
827
|
-
return {
|
|
828
|
-
parts,
|
|
829
|
-
...prerelease.length ? { prerelease: prerelease.join("-") } : {}
|
|
830
|
-
};
|
|
831
|
-
}
|
|
832
|
-
function compareVersions(a, b) {
|
|
833
|
-
for (let i = 0; i < 3; i++) {
|
|
834
|
-
const diff = (a.parts[i] ?? 0) - (b.parts[i] ?? 0);
|
|
835
|
-
if (diff !== 0) return diff;
|
|
836
|
-
}
|
|
837
|
-
if (a.prerelease && !b.prerelease) return -1;
|
|
838
|
-
if (!a.prerelease && b.prerelease) return 1;
|
|
839
|
-
if (a.prerelease && b.prerelease) return a.prerelease < b.prerelease ? -1 : a.prerelease > b.prerelease ? 1 : 0;
|
|
840
|
-
return 0;
|
|
841
|
-
}
|
|
842
|
-
function satisfiesComparator(version, comparator) {
|
|
843
|
-
const raw = comparator.trim();
|
|
844
|
-
if (!raw || raw === "*" || raw === "x") return true;
|
|
845
|
-
const operatorMatch = raw.match(/^([\^~]|>=|<=|[><=])?(.+)$/);
|
|
846
|
-
if (!operatorMatch) return false;
|
|
847
|
-
const operator = operatorMatch[1];
|
|
848
|
-
const rest = operatorMatch[2].trim();
|
|
849
|
-
const segments = rest.replace(/\.[x*]/gi, "").split(".").filter(Boolean);
|
|
850
|
-
const base = parseVersion(rest.replace(/[x*]/gi, "0"));
|
|
851
|
-
if (!base) return false;
|
|
852
|
-
switch (operator) {
|
|
853
|
-
case ">": return compareVersions(version, base) > 0;
|
|
854
|
-
case ">=": return compareVersions(version, base) >= 0;
|
|
855
|
-
case "<": return compareVersions(version, base) < 0;
|
|
856
|
-
case "<=": return compareVersions(version, base) <= 0;
|
|
857
|
-
case "^": {
|
|
858
|
-
if (compareVersions(version, base) < 0) return false;
|
|
859
|
-
const fixedIndex = base.parts.findIndex((part) => part !== 0);
|
|
860
|
-
const lockUpTo = fixedIndex === -1 ? base.parts.length - 1 : fixedIndex;
|
|
861
|
-
for (let i = 0; i <= lockUpTo; i++) if ((version.parts[i] ?? 0) !== (base.parts[i] ?? 0)) return false;
|
|
862
|
-
return true;
|
|
863
|
-
}
|
|
864
|
-
case "~": {
|
|
865
|
-
if (compareVersions(version, base) < 0) return false;
|
|
866
|
-
const lockUpTo = segments.length >= 2 ? 1 : 0;
|
|
867
|
-
for (let i = 0; i <= lockUpTo; i++) if ((version.parts[i] ?? 0) !== (base.parts[i] ?? 0)) return false;
|
|
868
|
-
return true;
|
|
869
|
-
}
|
|
870
|
-
default:
|
|
871
|
-
for (let i = 0; i < Math.max(segments.length, 3); i++) if (i < segments.length && (version.parts[i] ?? 0) !== (base.parts[i] ?? 0)) return false;
|
|
872
|
-
return segments.length >= 3 ? compareVersions(version, base) === 0 : true;
|
|
873
|
-
}
|
|
874
|
-
}
|
|
875
|
-
/**
|
|
876
|
-
* Pragmatic semver range check for service version declarations — supports
|
|
877
|
-
* the common forms (`1.2.3`, `^1.2.3`, `~1.2`, `>=1 <3`, `1.x`, `*`, and
|
|
878
|
-
* `||`-joined alternatives) without pulling in a semver dependency. An
|
|
879
|
-
* unparseable version or range reads as **not satisfied**.
|
|
880
|
-
*/
|
|
881
|
-
function satisfiesVersionRange(version, range) {
|
|
882
|
-
const parsed = parseVersion(version);
|
|
883
|
-
if (!parsed) return false;
|
|
884
|
-
const alternatives = range.split("||").map((alt) => alt.trim()).filter(Boolean);
|
|
885
|
-
if (alternatives.length === 0) return true;
|
|
886
|
-
return alternatives.some((alternative) => alternative.split(/\s+/).every((comparator) => satisfiesComparator(parsed, comparator)));
|
|
887
|
-
}
|
|
888
|
-
function isPlainObject(value) {
|
|
889
|
-
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
890
|
-
}
|
|
891
|
-
/** Deep-merge two values with the service option-set rules (see below). */
|
|
892
|
-
function deepMergeTwo(a, b) {
|
|
893
|
-
if (Array.isArray(a) && Array.isArray(b)) return [.../* @__PURE__ */ new Set([...a, ...b])];
|
|
894
|
-
if (isPlainObject(a) && isPlainObject(b)) {
|
|
895
|
-
const out = { ...a };
|
|
896
|
-
for (const key of Object.keys(b)) out[key] = key in a ? deepMergeTwo(a[key], b[key]) : b[key];
|
|
897
|
-
return out;
|
|
898
|
-
}
|
|
899
|
-
return b;
|
|
900
|
-
}
|
|
901
|
-
/**
|
|
902
|
-
* Default option-set merge when a service declares no `mergeOptions`:
|
|
903
|
-
* deep-merge in declaration order — objects recurse, arrays union-dedupe,
|
|
904
|
-
* scalars take the later value. Covers the built-in services (`roots` /
|
|
905
|
-
* `langs` union, `themes` per-key last-wins) without a custom hook.
|
|
906
|
-
*/
|
|
907
|
-
function deepMergeOptionSets(sets) {
|
|
908
|
-
return sets.reduce((merged, set) => deepMergeTwo(merged, set));
|
|
909
|
-
}
|
|
910
|
-
//#endregion
|
|
911
764
|
//#region src/node/host-services.ts
|
|
912
765
|
const debug = createDebug("devframe:services");
|
|
913
766
|
function isServiceDefinition(input) {
|
|
@@ -1,10 +1,11 @@
|
|
|
1
|
+
import { resolveClientAssets } from "./index.mjs";
|
|
1
2
|
import { DEVFRAME_CONNECTION_META_FILENAME } from "./constants.mjs";
|
|
2
3
|
import { t as diagnostics } from "./diagnostics-BXWW3VK-.mjs";
|
|
3
|
-
import { t as createHostContext } from "./context-
|
|
4
|
+
import { t as createHostContext } from "./context-omlma_1n.mjs";
|
|
4
5
|
import { t as resolveStaticAssetsSource } from "./remote-assets-DezQmPQU.mjs";
|
|
5
6
|
import { i as resolveMcpConnectionMeta, n as resolveBasePath, r as resolveDevServerPort, t as normalizeBasePath } from "./_shared-BM3PdYli.mjs";
|
|
6
7
|
import { t as createH3DevframeHost } from "./host-h3-fRbF9yor.mjs";
|
|
7
|
-
import { i as normalizeHttpServerUrl, n as resolveInstanceRegister, t as createInstanceShell } from "./instance-shell-
|
|
8
|
+
import { a as importRuntimeModule, i as normalizeHttpServerUrl, n as resolveInstanceRegister, t as createInstanceShell } from "./instance-shell-CpVW4zG0.mjs";
|
|
8
9
|
import { open } from "./utils/open.mjs";
|
|
9
10
|
import { mountStaticHandler } from "./utils/serve-static.mjs";
|
|
10
11
|
import { createServer } from "node:http";
|
|
@@ -37,7 +38,7 @@ function getInstanceInternals(handler) {
|
|
|
37
38
|
*/
|
|
38
39
|
function initDevframe(def, options) {
|
|
39
40
|
const base = normalizeBasePath(options.base);
|
|
40
|
-
const distDir = options.distDir === false ? void 0 : options.distDir ?? def
|
|
41
|
+
const distDir = options.distDir === false ? void 0 : options.distDir ?? resolveClientAssets(def);
|
|
41
42
|
const app = options.app ?? new H3();
|
|
42
43
|
const host = options.host ?? def.cli?.host ?? "localhost";
|
|
43
44
|
const shell = createInstanceShell({
|
|
@@ -91,7 +92,7 @@ function initDevframe(def, options) {
|
|
|
91
92
|
const mcpPath = joinURL(base, mcpMeta.path);
|
|
92
93
|
let mountMcpHttp;
|
|
93
94
|
try {
|
|
94
|
-
({mountMcpHttp} = await
|
|
95
|
+
({mountMcpHttp} = await importRuntimeModule("devframe/adapters/mcp"));
|
|
95
96
|
} catch (error) {
|
|
96
97
|
const reason = error instanceof Error ? error.message : String(error);
|
|
97
98
|
throw diagnostics.DF0017({
|
|
@@ -142,7 +143,7 @@ function initDevframe(def, options) {
|
|
|
142
143
|
* h3 + WebSocket RPC + (optionally) the author's SPA mounted at the
|
|
143
144
|
* resolved base path.
|
|
144
145
|
*
|
|
145
|
-
* When `distDir` is omitted (and
|
|
146
|
+
* When `distDir` is omitted (and the definition's client assets are unset) the
|
|
146
147
|
* server runs in **bridge mode**: only `__connection.json` and the WS
|
|
147
148
|
* endpoint are mounted, with no SPA mount. The SPA is expected to be
|
|
148
149
|
* hosted elsewhere (e.g. by a parent Vite/Nuxt dev server) — see
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
* broadcast notifications — so these names live in one place instead of
|
|
6
6
|
* scattered string literals.
|
|
7
7
|
*
|
|
8
|
-
* **Keep this in sync with [`docs/
|
|
8
|
+
* **Keep this in sync with [`docs/content/8.references/3.events.md`](../../../docs/content/8.references/3.events.md)**
|
|
9
9
|
* (the "Core devframe events" section): every name here appears in that page's
|
|
10
10
|
* tables, and every name there resolves to an entry here. Add, rename, or
|
|
11
11
|
* remove a name in both places in the same change, and reference
|
|
@@ -58,8 +58,22 @@ const DEVFRAME_EVENTS = {
|
|
|
58
58
|
streamingEnd: "devframe:streaming:end",
|
|
59
59
|
streamingUploadCancel: "devframe:streaming:upload-cancel"
|
|
60
60
|
},
|
|
61
|
+
/**
|
|
62
|
+
* In-page channel notifications the page script pushes to its panels
|
|
63
|
+
* (page script → panel), `devframe:` prefix. The paired request methods
|
|
64
|
+
* (`devframe:in-page:page-state:subscribe`/`set`/`patch`) are call
|
|
65
|
+
* endpoints, not events, and are defined at their handlers
|
|
66
|
+
* (`in-page-channel/state.ts`).
|
|
67
|
+
*/
|
|
68
|
+
inPageChannel: {
|
|
69
|
+
panelStateUpdated: "devframe:in-page:panel-state:updated",
|
|
70
|
+
panelStatePatch: "devframe:in-page:panel-state:patch"
|
|
71
|
+
},
|
|
61
72
|
/** `postMessage` channels the runtime posts across window boundaries. */
|
|
62
|
-
postMessage: {
|
|
73
|
+
postMessage: {
|
|
74
|
+
remoteAssetsError: "devframe:remote-assets-error",
|
|
75
|
+
inPageChannel: "devframe:in-page-channel"
|
|
76
|
+
}
|
|
63
77
|
};
|
|
64
78
|
//#endregion
|
|
65
79
|
export { DEVFRAME_EVENTS as t };
|
|
@@ -0,0 +1,306 @@
|
|
|
1
|
+
import { D as InferArgsType, E as Thenable, O as InferReturnType, T as RpcReturnSchema, i as RpcArgsSchema } from "../types-CMdPYhOx.mjs";
|
|
2
|
+
import { k as SharedState, zt as EventEmitter } from "../context-BhBzOXVa.mjs";
|
|
3
|
+
import { BirpcReturn } from "birpc";
|
|
4
|
+
//#region src/in-page-channel/types.d.ts
|
|
5
|
+
/**
|
|
6
|
+
* The shared contract of one in-page channel, declared once (usually in a
|
|
7
|
+
* `shared/protocol.ts` both sides import) and passed to both endpoints as a
|
|
8
|
+
* type parameter. Purely a type — the only runtime companion is the
|
|
9
|
+
* channel-name constant declared next to it.
|
|
10
|
+
*/
|
|
11
|
+
interface InPageChannelProtocol {
|
|
12
|
+
/** Functions implemented by the page script, callable by panels. */
|
|
13
|
+
pageScript?: Record<string, (...args: any[]) => any>;
|
|
14
|
+
/** Functions implemented by panels, callable by the page script. */
|
|
15
|
+
panel?: Record<string, (...args: any[]) => any>;
|
|
16
|
+
/**
|
|
17
|
+
* Shared-state slots. The page script is the authority: it owns the
|
|
18
|
+
* canonical value; panels are seeded on connect and converge through
|
|
19
|
+
* syncId-deduplicated patches.
|
|
20
|
+
*/
|
|
21
|
+
sharedStates?: Record<string, object>;
|
|
22
|
+
}
|
|
23
|
+
type SideFunctions<S> = S extends Record<string, (...args: any[]) => any> ? S : Record<string, never>;
|
|
24
|
+
type PageScriptFunctions<P extends InPageChannelProtocol> = SideFunctions<NonNullable<P['pageScript']>>;
|
|
25
|
+
type PanelFunctions<P extends InPageChannelProtocol> = SideFunctions<NonNullable<P['panel']>>;
|
|
26
|
+
type SharedStates<P extends InPageChannelProtocol> = P['sharedStates'] extends Record<string, object> ? P['sharedStates'] : Record<string, never>;
|
|
27
|
+
type FnArgs<F> = F extends ((...args: infer A) => any) ? A : never;
|
|
28
|
+
type FnReturn<F> = F extends ((...args: any[]) => infer R) ? Awaited<R> : never;
|
|
29
|
+
/**
|
|
30
|
+
* Types of an in-page channel function — `RpcFunctionType` minus the
|
|
31
|
+
* server-only `static`: `event` is fire-and-forget (the only type valid for
|
|
32
|
+
* fan-out), `action` performs, `query` requests data (the default).
|
|
33
|
+
*/
|
|
34
|
+
type InPageFunctionType = 'action' | 'event' | 'query';
|
|
35
|
+
/**
|
|
36
|
+
* An in-page channel function definition — the `defineRpcFunction` authoring
|
|
37
|
+
* shape (`name`, `type`, Standard-Schema `args`/`returns`,
|
|
38
|
+
* `jsonSerializable`, `handler`) narrowed to the browser: there is no
|
|
39
|
+
* `dump`/`snapshot`/`cacheable`/`agent`. When `jsonSerializable` is `true`,
|
|
40
|
+
* payloads are strictly validated at the receiving endpoint and misshapen
|
|
41
|
+
* values reject the call with a descriptive `InPageChannelError` instead of
|
|
42
|
+
* a cryptic `DataCloneError` in the port.
|
|
43
|
+
*/
|
|
44
|
+
type InPageFunctionDefinition<NAME extends string, TYPE extends InPageFunctionType = 'query', ARGS extends any[] = [], RETURN = void, AS extends RpcArgsSchema | undefined = undefined, RS extends RpcReturnSchema | undefined = undefined> = [AS, RS] extends [undefined, undefined] ? {
|
|
45
|
+
name: NAME;
|
|
46
|
+
type?: TYPE;
|
|
47
|
+
args?: AS;
|
|
48
|
+
returns?: RS;
|
|
49
|
+
jsonSerializable?: boolean;
|
|
50
|
+
handler: (...args: ARGS) => RETURN;
|
|
51
|
+
} : {
|
|
52
|
+
name: NAME;
|
|
53
|
+
type?: TYPE;
|
|
54
|
+
/** Standard Schema array validating (and typing) the arguments. */
|
|
55
|
+
args: AS;
|
|
56
|
+
/** Standard Schema typing the resolved return value. */
|
|
57
|
+
returns: RS;
|
|
58
|
+
jsonSerializable?: boolean;
|
|
59
|
+
handler: (...args: InferArgsType<AS>) => Thenable<InferReturnType<RS>>;
|
|
60
|
+
};
|
|
61
|
+
/** Loosely-typed definition — the registration unit both endpoints accept. */
|
|
62
|
+
type InPageFunctionDefinitionAny = InPageFunctionDefinition<string, any, any, any, any, any>;
|
|
63
|
+
/**
|
|
64
|
+
* Connection lifecycle of a panel endpoint: `connecting` (handshake retry
|
|
65
|
+
* loop running, outgoing traffic buffered) → `connected` → back to
|
|
66
|
+
* `connecting` on port loss, or `closed` after `close()` (permanent).
|
|
67
|
+
*/
|
|
68
|
+
type InPageChannelStatus = 'connecting' | 'connected' | 'closed';
|
|
69
|
+
interface InPageChannelCommonOptions {
|
|
70
|
+
/**
|
|
71
|
+
* Channel name, namespaced with the devframe id by convention
|
|
72
|
+
* (e.g. `devframes:plugin:a11y`). Both endpoints must use the same name.
|
|
73
|
+
*/
|
|
74
|
+
name: string;
|
|
75
|
+
/** Implementations of this endpoint's side of the protocol. */
|
|
76
|
+
functions?: readonly InPageFunctionDefinitionAny[];
|
|
77
|
+
/**
|
|
78
|
+
* Origins accepted during the handshake (and used as `targetOrigin` when
|
|
79
|
+
* posting handshake messages). The in-page channel is same-origin by
|
|
80
|
+
* definition, so this defaults to `[location.origin]`.
|
|
81
|
+
*/
|
|
82
|
+
allowedOrigins?: string[];
|
|
83
|
+
/**
|
|
84
|
+
* Timeout for request/response calls, in milliseconds; `-1` disables.
|
|
85
|
+
* Rejections are `InPageChannelError`s (code `timeout`) carrying the
|
|
86
|
+
* endpoint status, so a hanging call explains itself.
|
|
87
|
+
* @default 15000
|
|
88
|
+
*/
|
|
89
|
+
callTimeoutMs?: number;
|
|
90
|
+
/**
|
|
91
|
+
* Liveness heartbeat guarding against silently dead ports. Defaults to a
|
|
92
|
+
* 5s ping / 12s silence window; pass `false` to disable — on both
|
|
93
|
+
* endpoints together.
|
|
94
|
+
*/
|
|
95
|
+
heartbeat?: {
|
|
96
|
+
intervalMs?: number;
|
|
97
|
+
timeoutMs?: number;
|
|
98
|
+
} | false;
|
|
99
|
+
/**
|
|
100
|
+
* Applied to each outgoing argument and handler result before posting —
|
|
101
|
+
* the place to unwrap framework reactivity (Vue `toRaw`, Solid `unwrap`)
|
|
102
|
+
* into plain structured-cloneable values.
|
|
103
|
+
*/
|
|
104
|
+
serialize?: (value: unknown) => unknown;
|
|
105
|
+
/** Applied to each incoming argument and call result. */
|
|
106
|
+
deserialize?: (value: unknown) => unknown;
|
|
107
|
+
}
|
|
108
|
+
/** Options for {@link createPageScriptChannel}. */
|
|
109
|
+
interface CreatePageScriptChannelOptions extends InPageChannelCommonOptions {
|
|
110
|
+
/**
|
|
111
|
+
* Window whose `message` events carry panel hellos. Defaults to the
|
|
112
|
+
* global `window`; pass `false` to skip the handshake listener entirely
|
|
113
|
+
* (bring-your-own ports via `addPanelPort` only).
|
|
114
|
+
*/
|
|
115
|
+
window?: Window | false;
|
|
116
|
+
}
|
|
117
|
+
/** Options for {@link connectPanelChannel}. */
|
|
118
|
+
interface ConnectPanelChannelOptions extends InPageChannelCommonOptions {
|
|
119
|
+
/**
|
|
120
|
+
* The panel's own window (listens for the handshake grant). Defaults to
|
|
121
|
+
* the global `window`; pass `false` with `transport` to skip the handshake.
|
|
122
|
+
*/
|
|
123
|
+
window?: Window | false;
|
|
124
|
+
/**
|
|
125
|
+
* Windows the hello is posted to. Defaults to the panel's ancestor chain
|
|
126
|
+
* plus its `opener` — the places a same-tab page script can live. When
|
|
127
|
+
* empty and no `transport` is given, the endpoint stays `connecting` and
|
|
128
|
+
* warns once.
|
|
129
|
+
*/
|
|
130
|
+
targets?: Window[];
|
|
131
|
+
/** Pre-established port to the page script, bypassing the handshake. */
|
|
132
|
+
transport?: MessagePort;
|
|
133
|
+
/**
|
|
134
|
+
* Pin this panel to one page-script instance id. By default the panel
|
|
135
|
+
* auto-pairs with the most recent page script that answers — almost
|
|
136
|
+
* always "my own tab's page script".
|
|
137
|
+
*/
|
|
138
|
+
instanceId?: string;
|
|
139
|
+
/**
|
|
140
|
+
* Base interval between handshake hello retries, in milliseconds; each
|
|
141
|
+
* retry backs off ×1.5 up to a 3s cap, forever (the page script may load
|
|
142
|
+
* later than the panel).
|
|
143
|
+
* @default 300
|
|
144
|
+
*/
|
|
145
|
+
helloIntervalMs?: number;
|
|
146
|
+
/**
|
|
147
|
+
* Maximum `callEvent` payloads buffered while `connecting`, flushed on
|
|
148
|
+
* connect; when full, the oldest is dropped with a console warning.
|
|
149
|
+
* @default 64
|
|
150
|
+
*/
|
|
151
|
+
eventBufferLimit?: number;
|
|
152
|
+
}
|
|
153
|
+
/**
|
|
154
|
+
* The channel shared-state accessor — mirrors `rpc.sharedState`, with the
|
|
155
|
+
* page script playing the server's role as rendezvous and authority. The
|
|
156
|
+
* page script's first `get` of a key must provide `initialValue`; a panel's
|
|
157
|
+
* `get` without one resolves once the authority's first replay arrives.
|
|
158
|
+
*/
|
|
159
|
+
interface InPageSharedStateHost<P extends InPageChannelProtocol> {
|
|
160
|
+
get: <K extends keyof SharedStates<P> & string>(key: K, options?: {
|
|
161
|
+
initialValue?: SharedStates<P>[K];
|
|
162
|
+
}) => Promise<SharedState<SharedStates<P>[K]>>;
|
|
163
|
+
}
|
|
164
|
+
/** Emitter events of a page-script endpoint. */
|
|
165
|
+
interface PageScriptChannelEvents<P extends InPageChannelProtocol> {
|
|
166
|
+
'panel:connected': (panel: PanelPeer<P>) => void;
|
|
167
|
+
'panel:disconnected': (panel: PanelPeer<P>) => void;
|
|
168
|
+
}
|
|
169
|
+
/** One connected panel, as seen from the page script. */
|
|
170
|
+
interface PanelPeer<P extends InPageChannelProtocol> {
|
|
171
|
+
/** Unique id of the panel endpoint (stable across its lifetime, not reloads). */
|
|
172
|
+
readonly id: string;
|
|
173
|
+
/** Call one panel's function and await the result. */
|
|
174
|
+
call: <K extends keyof PanelFunctions<P> & string>(name: K, ...args: FnArgs<PanelFunctions<P>[K]>) => Promise<FnReturn<PanelFunctions<P>[K]>>;
|
|
175
|
+
/** Disconnect this panel. */
|
|
176
|
+
close: () => void;
|
|
177
|
+
}
|
|
178
|
+
/**
|
|
179
|
+
* The page-script endpoint of an in-page channel: answers panel handshakes,
|
|
180
|
+
* holds one dedicated port per connected panel, fans events out to all of
|
|
181
|
+
* them, and is the authority for the channel's shared states.
|
|
182
|
+
*/
|
|
183
|
+
interface PageScriptChannel<P extends InPageChannelProtocol> {
|
|
184
|
+
readonly name: string;
|
|
185
|
+
/**
|
|
186
|
+
* This page context's instance id (persisted per tab in sessionStorage),
|
|
187
|
+
* carried in every handshake so panels can pin to one instance when the
|
|
188
|
+
* same app is open in several tabs.
|
|
189
|
+
*/
|
|
190
|
+
readonly instanceId: string;
|
|
191
|
+
/** Currently connected panels. */
|
|
192
|
+
readonly panels: readonly PanelPeer<P>[];
|
|
193
|
+
readonly events: Pick<EventEmitter<PageScriptChannelEvents<P>>, 'on' | 'once'>;
|
|
194
|
+
/**
|
|
195
|
+
* Fan a fire-and-forget event out to every connected panel; panels that
|
|
196
|
+
* don't implement the function ignore it.
|
|
197
|
+
*/
|
|
198
|
+
callEvent: <K extends keyof PanelFunctions<P> & string>(name: K, ...args: FnArgs<PanelFunctions<P>[K]>) => void;
|
|
199
|
+
/** Page-script-authoritative shared states, replayed to joining panels. */
|
|
200
|
+
readonly sharedState: InPageSharedStateHost<P>;
|
|
201
|
+
/** Adopt a pre-established port as a panel peer (bring-your-own transport). */
|
|
202
|
+
addPanelPort: (port: MessagePort) => PanelPeer<P>;
|
|
203
|
+
/** Tear the endpoint down: disconnect every panel, stop answering hellos. */
|
|
204
|
+
close: () => void;
|
|
205
|
+
}
|
|
206
|
+
/** Emitter events of a panel endpoint. */
|
|
207
|
+
interface PanelChannelEvents {
|
|
208
|
+
'status:updated': (status: InPageChannelStatus) => void;
|
|
209
|
+
}
|
|
210
|
+
/**
|
|
211
|
+
* The panel endpoint of an in-page channel: finds the page script with a
|
|
212
|
+
* retrying same-origin handshake, survives reloads on either side by
|
|
213
|
+
* re-handshaking, and buffers outgoing traffic while `connecting`.
|
|
214
|
+
*/
|
|
215
|
+
interface PanelChannel<P extends InPageChannelProtocol> {
|
|
216
|
+
readonly name: string;
|
|
217
|
+
readonly status: InPageChannelStatus;
|
|
218
|
+
/** The paired page script's instance id, once connected. */
|
|
219
|
+
readonly pageScript: {
|
|
220
|
+
instanceId: string;
|
|
221
|
+
} | undefined;
|
|
222
|
+
readonly events: Pick<EventEmitter<PanelChannelEvents>, 'on' | 'once'>;
|
|
223
|
+
/**
|
|
224
|
+
* Resolves once connected. With `timeoutMs`, rejects with an
|
|
225
|
+
* `InPageChannelError` (code `timeout`) when no page script answered in
|
|
226
|
+
* time — the hook for a "no page script found" fallback UI.
|
|
227
|
+
*/
|
|
228
|
+
whenConnected: (timeoutMs?: number) => Promise<void>;
|
|
229
|
+
/**
|
|
230
|
+
* Call a page-script function and await the result. While `connecting`
|
|
231
|
+
* the call is buffered and sent on connect; it rejects with code
|
|
232
|
+
* `timeout` when `callTimeoutMs` elapses first.
|
|
233
|
+
*/
|
|
234
|
+
call: <K extends keyof PageScriptFunctions<P> & string>(name: K, ...args: FnArgs<PageScriptFunctions<P>[K]>) => Promise<FnReturn<PageScriptFunctions<P>[K]>>;
|
|
235
|
+
/**
|
|
236
|
+
* Fire-and-forget to the page script. While `connecting` the event is
|
|
237
|
+
* buffered (up to `eventBufferLimit`) and flushed on connect.
|
|
238
|
+
*/
|
|
239
|
+
callEvent: <K extends keyof PageScriptFunctions<P> & string>(name: K, ...args: FnArgs<PageScriptFunctions<P>[K]>) => void;
|
|
240
|
+
/** Shared states mirrored from the page-script authority. */
|
|
241
|
+
readonly sharedState: InPageSharedStateHost<P>;
|
|
242
|
+
/** Tear the endpoint down permanently. */
|
|
243
|
+
close: () => void;
|
|
244
|
+
}
|
|
245
|
+
//#endregion
|
|
246
|
+
//#region src/in-page-channel/internal.d.ts
|
|
247
|
+
/** Stable failure codes of the in-page channel. */
|
|
248
|
+
type InPageChannelErrorCode = 'timeout' |
|
|
249
|
+
/** The endpoint was closed (or closed while calls were pending). */
|
|
250
|
+
'closed' |
|
|
251
|
+
/** A `jsonSerializable` payload contained a non-JSON value. */
|
|
252
|
+
'not-serializable' |
|
|
253
|
+
/** The port refused to clone a payload (`DataCloneError`). */
|
|
254
|
+
'not-cloneable' |
|
|
255
|
+
/** Standard-Schema validation of incoming arguments failed. */
|
|
256
|
+
'invalid-args' |
|
|
257
|
+
/** A shared-state key was first accessed without its initial value. */
|
|
258
|
+
'state-uninitialized';
|
|
259
|
+
/** A coded in-page channel error; every failure mode carries a stable `code`. */
|
|
260
|
+
declare class InPageChannelError extends Error {
|
|
261
|
+
readonly code: InPageChannelErrorCode;
|
|
262
|
+
name: string;
|
|
263
|
+
constructor(code: InPageChannelErrorCode, message: string, options?: {
|
|
264
|
+
cause?: unknown;
|
|
265
|
+
});
|
|
266
|
+
}
|
|
267
|
+
//#endregion
|
|
268
|
+
//#region src/in-page-channel/page-script.d.ts
|
|
269
|
+
/**
|
|
270
|
+
* Create the page-script endpoint of an in-page channel.
|
|
271
|
+
*
|
|
272
|
+
* It listens for panel hellos on the host page's window and answers each
|
|
273
|
+
* with a dedicated `MessageChannel` port (same-origin enforced both ways),
|
|
274
|
+
* keeping one live peer per panel — dock iframe, popup, and Document-PiP
|
|
275
|
+
* panels all handshake the same way, and a panel reload is simply a new
|
|
276
|
+
* handshake. No server is involved at any point.
|
|
277
|
+
*/
|
|
278
|
+
declare function createPageScriptChannel<P extends InPageChannelProtocol>(options: CreatePageScriptChannelOptions): PageScriptChannel<P>;
|
|
279
|
+
//#endregion
|
|
280
|
+
//#region src/in-page-channel/panel.d.ts
|
|
281
|
+
/**
|
|
282
|
+
* Connect the panel endpoint of an in-page channel.
|
|
283
|
+
*
|
|
284
|
+
* The panel initiates: it posts a versioned hello to every window a
|
|
285
|
+
* same-tab page script can live in (its ancestor chain and its `opener`),
|
|
286
|
+
* retrying with backoff until one answers with a dedicated port — so boot
|
|
287
|
+
* order never matters, and a reload of either side is just a re-handshake
|
|
288
|
+
* (`WindowProxy` references survive navigations). While `connecting`,
|
|
289
|
+
* outgoing calls and events are buffered; when no page script exists at all
|
|
290
|
+
* (e.g. the panel opened standalone), the endpoint stays `connecting` and
|
|
291
|
+
* the UI can key a fallback state off `status` / `whenConnected()`.
|
|
292
|
+
*/
|
|
293
|
+
declare function connectPanelChannel<P extends InPageChannelProtocol>(options: ConnectPanelChannelOptions): PanelChannel<P>;
|
|
294
|
+
//#endregion
|
|
295
|
+
//#region src/in-page-channel/index.d.ts
|
|
296
|
+
/**
|
|
297
|
+
* Define one in-page channel function — the `defineRpcFunction` authoring
|
|
298
|
+
* shape narrowed to the browser (see {@link InPageFunctionDefinition}).
|
|
299
|
+
* Pure identity: it only types the definition. Functions live in
|
|
300
|
+
* side-specific files and are passed to their endpoint via `functions`; the
|
|
301
|
+
* shared protocol file carries only the contract type and the channel-name
|
|
302
|
+
* constant.
|
|
303
|
+
*/
|
|
304
|
+
declare function defineChannelFunction<NAME extends string, TYPE extends InPageFunctionType, ARGS extends any[], RETURN = void, const AS extends RpcArgsSchema | undefined = undefined, const RS extends RpcReturnSchema | undefined = undefined>(definition: InPageFunctionDefinition<NAME, TYPE, ARGS, RETURN, AS, RS>): InPageFunctionDefinition<NAME, TYPE, ARGS, RETURN, AS, RS>;
|
|
305
|
+
//#endregion
|
|
306
|
+
export { type ConnectPanelChannelOptions, type CreatePageScriptChannelOptions, InPageChannelError, type InPageChannelErrorCode, type InPageChannelProtocol, type InPageChannelStatus, type InPageFunctionDefinition, type PageScriptChannel, type PanelChannel, type PanelPeer, connectPanelChannel, createPageScriptChannel, defineChannelFunction };
|