@astrale-os/shell 0.1.1 → 0.2.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/LICENSE +202 -0
- package/dist/application/apps.d.ts +18 -0
- package/dist/application/apps.d.ts.map +1 -0
- package/dist/application/apps.js +35 -0
- package/dist/application/namespaces.d.ts +21 -0
- package/dist/application/namespaces.d.ts.map +1 -0
- package/dist/application/namespaces.js +12 -0
- package/dist/application/session/open.d.ts +19 -0
- package/dist/application/session/open.d.ts.map +1 -0
- package/dist/application/session/open.js +46 -0
- package/dist/application/session/session.d.ts +41 -0
- package/dist/application/session/session.d.ts.map +1 -0
- package/dist/application/session/session.js +9 -0
- package/dist/application/session/token.d.ts +24 -0
- package/dist/application/session/token.d.ts.map +1 -0
- package/dist/application/session/token.js +51 -0
- package/dist/application/spaces.d.ts +17 -0
- package/dist/application/spaces.d.ts.map +1 -0
- package/dist/application/spaces.js +30 -0
- package/dist/application/user.d.ts +20 -0
- package/dist/application/user.d.ts.map +1 -0
- package/dist/application/user.js +26 -0
- package/dist/application/view.d.ts +20 -0
- package/dist/application/view.d.ts.map +1 -0
- package/dist/application/view.js +18 -0
- package/dist/{application/channels/children-channel.d.ts → channel/children.d.ts} +4 -4
- package/dist/channel/children.d.ts.map +1 -0
- package/dist/channel/listeners.d.ts +8 -0
- package/dist/channel/listeners.d.ts.map +1 -0
- package/dist/{adapters/message-port.transport.d.ts → channel/message-port.d.ts} +2 -2
- package/dist/channel/message-port.d.ts.map +1 -0
- package/dist/{application/channels → channel}/observer.d.ts +2 -1
- package/dist/channel/observer.d.ts.map +1 -0
- package/dist/{application/channels/parent-channel.d.ts → channel/parent.d.ts} +4 -4
- package/dist/channel/parent.d.ts.map +1 -0
- package/dist/{application/channels/parent-channel.js → channel/parent.js} +1 -1
- package/dist/channel/transport.d.ts +8 -0
- package/dist/channel/transport.d.ts.map +1 -0
- package/dist/index.d.ts +56 -41
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +23 -20
- package/dist/{domain/intent → intent}/middleware/capabilities.d.ts +2 -2
- package/dist/intent/middleware/capabilities.d.ts.map +1 -0
- package/dist/intent/middleware/logging.d.ts.map +1 -0
- package/dist/{domain/intent → intent}/middleware/rate-limit.d.ts +1 -1
- package/dist/intent/middleware/rate-limit.d.ts.map +1 -0
- package/dist/{application/intent/pipeline-runner.d.ts → intent/pipeline.d.ts} +3 -3
- package/dist/intent/pipeline.d.ts.map +1 -0
- package/dist/intent/policy.d.ts +40 -0
- package/dist/intent/policy.d.ts.map +1 -0
- package/dist/intent/policy.js +15 -0
- package/dist/{application/intent → intent}/request.d.ts +5 -14
- package/dist/intent/request.d.ts.map +1 -0
- package/dist/{application/intent → intent}/request.js +6 -20
- package/dist/intent/router.d.ts +31 -0
- package/dist/intent/router.d.ts.map +1 -0
- package/dist/{application/intent → intent}/router.js +1 -15
- package/dist/kernel/client.d.ts +33 -0
- package/dist/kernel/client.d.ts.map +1 -0
- package/dist/kernel/credential.d.ts +35 -0
- package/dist/kernel/credential.d.ts.map +1 -0
- package/dist/kernel/credential.js +43 -0
- package/dist/kernel/delegated.d.ts +17 -0
- package/dist/kernel/delegated.d.ts.map +1 -0
- package/dist/kernel/delegated.js +29 -0
- package/dist/{application/windowing/token-refresh.d.ts → kernel/delegation/refresh.d.ts} +2 -2
- package/dist/kernel/delegation/refresh.d.ts.map +1 -0
- package/dist/{application/windowing/token-refresh.js → kernel/delegation/refresh.js} +1 -1
- package/dist/{domain/identity/delegation.d.ts → kernel/delegation/token.d.ts} +1 -1
- package/dist/kernel/delegation/token.d.ts.map +1 -0
- package/dist/{adapters/kernel-client.adapter.d.ts → kernel/session.d.ts} +15 -12
- package/dist/kernel/session.d.ts.map +1 -0
- package/dist/{adapters/kernel-client.adapter.js → kernel/session.js} +10 -15
- package/dist/message/ctrl.d.ts +34 -0
- package/dist/message/ctrl.d.ts.map +1 -0
- package/dist/message/error.d.ts +9 -0
- package/dist/message/error.d.ts.map +1 -0
- package/dist/{application/windowing/protocol.d.ts → message/init.d.ts} +1 -1
- package/dist/message/init.d.ts.map +1 -0
- package/dist/{domain/message/registries.d.ts → message/intent.d.ts} +45 -37
- package/dist/message/intent.d.ts.map +1 -0
- package/dist/message/message.d.ts +10 -0
- package/dist/message/message.d.ts.map +1 -0
- package/dist/shell/access.d.ts +10 -0
- package/dist/shell/access.d.ts.map +1 -0
- package/dist/shell/access.js +19 -0
- package/dist/shell/build.d.ts +28 -0
- package/dist/shell/build.d.ts.map +1 -0
- package/dist/shell/build.js +58 -0
- package/dist/shell/config.d.ts +29 -0
- package/dist/shell/config.d.ts.map +1 -0
- package/dist/shell/create.d.ts +4 -0
- package/dist/shell/create.d.ts.map +1 -0
- package/dist/shell/create.js +5 -0
- package/dist/{application/windowing/child-init.d.ts → shell/sandboxed/boot.d.ts} +5 -5
- package/dist/shell/sandboxed/boot.d.ts.map +1 -0
- package/dist/{application/windowing/child-init.js → shell/sandboxed/boot.js} +5 -6
- package/dist/shell/sandboxed/guarded.d.ts +13 -0
- package/dist/shell/sandboxed/guarded.d.ts.map +1 -0
- package/dist/shell/sandboxed/guarded.js +28 -0
- package/dist/shell/sandboxed/pending.d.ts +14 -0
- package/dist/shell/sandboxed/pending.d.ts.map +1 -0
- package/dist/shell/sandboxed/pending.js +30 -0
- package/dist/shell/sandboxed/sandboxed.d.ts +4 -0
- package/dist/shell/sandboxed/sandboxed.d.ts.map +1 -0
- package/dist/shell/sandboxed/sandboxed.js +100 -0
- package/dist/shell/shell.d.ts +36 -0
- package/dist/shell/shell.d.ts.map +1 -0
- package/dist/shell/standalone.d.ts +4 -0
- package/dist/shell/standalone.d.ts.map +1 -0
- package/dist/shell/standalone.js +85 -0
- package/dist/{domain/window/config.d.ts → window/capabilities.d.ts} +3 -3
- package/dist/window/capabilities.d.ts.map +1 -0
- package/dist/{ports/shell-adapter.d.ts → window/embed/adapter.d.ts} +3 -2
- package/dist/window/embed/adapter.d.ts.map +1 -0
- package/dist/{adapters/iframe.shell-adapter.d.ts → window/embed/iframe.d.ts} +2 -2
- package/dist/window/embed/iframe.d.ts.map +1 -0
- package/dist/{application/windowing/lifecycle-controller.d.ts → window/lifecycle/states.d.ts} +4 -3
- package/dist/window/lifecycle/states.d.ts.map +1 -0
- package/dist/{application/windowing/lifecycle-controller.js → window/lifecycle/states.js} +1 -1
- package/dist/{domain/window/lifecycle.d.ts → window/lifecycle/transition.d.ts} +3 -3
- package/dist/window/lifecycle/transition.d.ts.map +1 -0
- package/dist/{domain/window/lifecycle.js → window/lifecycle/transition.js} +1 -1
- package/dist/window/mount/close.d.ts +27 -0
- package/dist/window/mount/close.d.ts.map +1 -0
- package/dist/window/mount/close.js +74 -0
- package/dist/window/mount/credential.d.ts +41 -0
- package/dist/window/mount/credential.d.ts.map +1 -0
- package/dist/window/mount/credential.js +74 -0
- package/dist/window/mount/handshake.d.ts.map +1 -0
- package/dist/{application/windowing → window/mount}/handshake.js +1 -1
- package/dist/{application/windowing/mount-controller.d.ts → window/mount/mount.d.ts} +7 -7
- package/dist/window/mount/mount.d.ts.map +1 -0
- package/dist/window/mount/mount.js +143 -0
- package/dist/window/mount/params.d.ts +73 -0
- package/dist/window/mount/params.d.ts.map +1 -0
- package/dist/window/mount/params.js +1 -0
- package/dist/window/mount/plain.d.ts +20 -0
- package/dist/window/mount/plain.d.ts.map +1 -0
- package/dist/window/mount/plain.js +46 -0
- package/dist/{domain/window → window}/window.d.ts +1 -1
- package/dist/window/window.d.ts.map +1 -0
- package/dist/window/window.js +1 -0
- package/package.json +11 -6
- package/src/application/apps.ts +60 -0
- package/src/application/namespaces.ts +38 -0
- package/src/application/session/open.ts +73 -0
- package/src/application/session/session.ts +46 -0
- package/src/application/session/token.ts +87 -0
- package/src/application/spaces.ts +52 -0
- package/src/application/user.ts +54 -0
- package/src/application/view.ts +42 -0
- package/src/{application/channels/children-channel.ts → channel/children.ts} +3 -3
- package/src/{application/channels/types.ts → channel/listeners.ts} +2 -7
- package/src/{adapters/message-port.transport.ts → channel/message-port.ts} +2 -2
- package/src/{application/channels → channel}/observer.ts +2 -1
- package/src/{application/channels/parent-channel.ts → channel/parent.ts} +4 -4
- package/src/{ports → channel}/transport.ts +2 -1
- package/src/index.ts +80 -88
- package/src/{domain/intent → intent}/middleware/capabilities.ts +2 -3
- package/src/{domain/intent → intent}/middleware/logging.ts +1 -1
- package/src/{domain/intent → intent}/middleware/rate-limit.ts +1 -1
- package/src/{application/intent/pipeline-runner.ts → intent/pipeline.ts} +3 -2
- package/src/intent/policy.ts +46 -0
- package/src/{application/intent → intent}/request.ts +14 -34
- package/src/{application/intent → intent}/router.ts +12 -49
- package/src/kernel/client.ts +33 -0
- package/src/kernel/credential.ts +78 -0
- package/src/kernel/delegated.ts +49 -0
- package/src/{application/windowing/token-refresh.ts → kernel/delegation/refresh.ts} +2 -2
- package/src/{adapters/kernel-client.adapter.ts → kernel/session.ts} +26 -33
- package/src/message/ctrl.ts +25 -0
- package/src/{domain/message/errors.ts → message/error.ts} +8 -0
- package/src/message/intent.ts +98 -0
- package/src/message/message.ts +11 -0
- package/src/shell/access.ts +26 -0
- package/src/shell/build.ts +95 -0
- package/src/shell/config.ts +32 -0
- package/src/shell/create.ts +9 -0
- package/src/{application/windowing/child-init.ts → shell/sandboxed/boot.ts} +10 -11
- package/src/shell/sandboxed/guarded.ts +32 -0
- package/src/shell/sandboxed/pending.ts +52 -0
- package/src/shell/sandboxed/sandboxed.ts +131 -0
- package/src/shell/shell.ts +37 -0
- package/src/shell/standalone.ts +97 -0
- package/src/{domain/window/config.ts → window/capabilities.ts} +2 -2
- package/src/{ports/shell-adapter.ts → window/embed/adapter.ts} +2 -1
- package/src/{adapters/iframe.shell-adapter.ts → window/embed/iframe.ts} +2 -2
- package/src/{application/windowing/lifecycle-controller.ts → window/lifecycle/states.ts} +3 -2
- package/src/{domain/window/lifecycle.ts → window/lifecycle/transition.ts} +2 -2
- package/src/window/mount/close.ts +111 -0
- package/src/window/mount/credential.ts +101 -0
- package/src/{application/windowing → window/mount}/handshake.ts +3 -2
- package/src/window/mount/mount.ts +185 -0
- package/src/window/mount/params.ts +64 -0
- package/src/window/mount/plain.ts +68 -0
- package/src/{domain/window → window}/window.ts +1 -1
- package/dist/adapters/iframe.shell-adapter.d.ts.map +0 -1
- package/dist/adapters/kernel-client.adapter.d.ts.map +0 -1
- package/dist/adapters/message-port.transport.d.ts.map +0 -1
- package/dist/application/channels/children-channel.d.ts.map +0 -1
- package/dist/application/channels/observer.d.ts.map +0 -1
- package/dist/application/channels/parent-channel.d.ts.map +0 -1
- package/dist/application/channels/types.d.ts +0 -12
- package/dist/application/channels/types.d.ts.map +0 -1
- package/dist/application/intent/pipeline-runner.d.ts.map +0 -1
- package/dist/application/intent/request.d.ts.map +0 -1
- package/dist/application/intent/router.d.ts +0 -56
- package/dist/application/intent/router.d.ts.map +0 -1
- package/dist/application/kernel-facade.d.ts +0 -33
- package/dist/application/kernel-facade.d.ts.map +0 -1
- package/dist/application/kernel-facade.js +0 -77
- package/dist/application/shell.d.ts +0 -100
- package/dist/application/shell.d.ts.map +0 -1
- package/dist/application/shell.js +0 -256
- package/dist/application/windowing/child-init.d.ts.map +0 -1
- package/dist/application/windowing/handshake.d.ts.map +0 -1
- package/dist/application/windowing/lifecycle-controller.d.ts.map +0 -1
- package/dist/application/windowing/mount-controller.d.ts.map +0 -1
- package/dist/application/windowing/mount-controller.js +0 -277
- package/dist/application/windowing/protocol.d.ts.map +0 -1
- package/dist/application/windowing/token-refresh.d.ts.map +0 -1
- package/dist/domain/identity/delegation.d.ts.map +0 -1
- package/dist/domain/identity/path.d.ts +0 -11
- package/dist/domain/identity/path.d.ts.map +0 -1
- package/dist/domain/identity/path.js +0 -13
- package/dist/domain/identity/resolve-self.d.ts +0 -21
- package/dist/domain/identity/resolve-self.d.ts.map +0 -1
- package/dist/domain/identity/resolve-self.js +0 -36
- package/dist/domain/intent/middleware/capabilities.d.ts.map +0 -1
- package/dist/domain/intent/middleware/logging.d.ts.map +0 -1
- package/dist/domain/intent/middleware/rate-limit.d.ts.map +0 -1
- package/dist/domain/intent/pipeline.d.ts +0 -3
- package/dist/domain/intent/pipeline.d.ts.map +0 -1
- package/dist/domain/intent/router.d.ts +0 -6
- package/dist/domain/intent/router.d.ts.map +0 -1
- package/dist/domain/message/errors.d.ts +0 -2
- package/dist/domain/message/errors.d.ts.map +0 -1
- package/dist/domain/message/registries.d.ts.map +0 -1
- package/dist/domain/message/types.d.ts +0 -30
- package/dist/domain/message/types.d.ts.map +0 -1
- package/dist/domain/window/config.d.ts.map +0 -1
- package/dist/domain/window/lifecycle.d.ts.map +0 -1
- package/dist/domain/window/window.d.ts.map +0 -1
- package/dist/ports/kernel-client.d.ts +0 -33
- package/dist/ports/kernel-client.d.ts.map +0 -1
- package/dist/ports/shell-adapter.d.ts.map +0 -1
- package/dist/ports/transport.d.ts +0 -7
- package/dist/ports/transport.d.ts.map +0 -1
- package/src/application/kernel-facade.ts +0 -143
- package/src/application/shell.ts +0 -433
- package/src/application/windowing/mount-controller.ts +0 -335
- package/src/domain/identity/path.ts +0 -14
- package/src/domain/identity/resolve-self.ts +0 -38
- package/src/domain/intent/pipeline.ts +0 -3
- package/src/domain/intent/router.ts +0 -6
- package/src/domain/message/registries.ts +0 -76
- package/src/domain/message/types.ts +0 -32
- package/src/ports/kernel-client.ts +0 -32
- /package/dist/{application/channels/children-channel.js → channel/children.js} +0 -0
- /package/dist/{application/channels/types.js → channel/listeners.js} +0 -0
- /package/dist/{adapters/message-port.transport.js → channel/message-port.js} +0 -0
- /package/dist/{application/channels → channel}/observer.js +0 -0
- /package/dist/{ports → channel}/transport.js +0 -0
- /package/dist/{domain/intent → intent}/middleware/capabilities.js +0 -0
- /package/dist/{domain/intent → intent}/middleware/logging.d.ts +0 -0
- /package/dist/{domain/intent → intent}/middleware/logging.js +0 -0
- /package/dist/{domain/intent → intent}/middleware/rate-limit.js +0 -0
- /package/dist/{application/intent/pipeline-runner.js → intent/pipeline.js} +0 -0
- /package/dist/{domain/intent/pipeline.js → kernel/client.js} +0 -0
- /package/dist/{domain/identity/delegation.js → kernel/delegation/token.js} +0 -0
- /package/dist/{domain/intent/router.js → message/ctrl.js} +0 -0
- /package/dist/{domain/message/errors.js → message/error.js} +0 -0
- /package/dist/{application/windowing/protocol.js → message/init.js} +0 -0
- /package/dist/{domain/message/registries.js → message/intent.js} +0 -0
- /package/dist/{domain/message/types.js → message/message.js} +0 -0
- /package/dist/{domain/window → shell}/config.js +0 -0
- /package/dist/{domain/window/window.js → shell/shell.js} +0 -0
- /package/dist/{ports/kernel-client.js → window/capabilities.js} +0 -0
- /package/dist/{ports/shell-adapter.js → window/embed/adapter.js} +0 -0
- /package/dist/{adapters/iframe.shell-adapter.js → window/embed/iframe.js} +0 -0
- /package/dist/{application/windowing → window/mount}/handshake.d.ts +0 -0
- /package/src/{domain/identity/delegation.ts → kernel/delegation/token.ts} +0 -0
- /package/src/{application/windowing/protocol.ts → message/init.ts} +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/kernel/client.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,2BAA2B,CAAA;AACtD,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,mCAAmC,CAAA;AAE/E;;;;;;;GAOG;AACH,MAAM,MAAM,YAAY,GAAG,sBAAsB,CAAC,KAAK,CAAC,GAAG;IACzD;;;OAGG;IACH,cAAc,IAAI,OAAO,CAAC,MAAM,CAAC,CAAA;IACjC;;;OAGG;IACH,SAAS,IAAI,MAAM,CAAA;IACnB;;;;;;;;OAQG;IACH,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAA;CACrB,CAAA"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import type { KernelClient } from './client';
|
|
2
|
+
import type { KernelClientAdapter } from './session';
|
|
3
|
+
export type KernelFacadeConfig = {
|
|
4
|
+
adapter: KernelClientAdapter;
|
|
5
|
+
credential?: string;
|
|
6
|
+
getCredential?: () => string;
|
|
7
|
+
/** Kernel URL — exposed to consumers via `KernelClient.url`. */
|
|
8
|
+
url: string;
|
|
9
|
+
/**
|
|
10
|
+
* Explicit identity node to use as the mint subject. When omitted, the mint
|
|
11
|
+
* resolves the AUTHENTICATED caller via `whoami` (so a cookie-fronted GUI mints
|
|
12
|
+
* as the logged-in user, not the kernel root). Set this only to pin a subject.
|
|
13
|
+
*/
|
|
14
|
+
mintIdentity?: string;
|
|
15
|
+
};
|
|
16
|
+
export interface KernelFacadeController extends KernelClient {
|
|
17
|
+
dispose(): void;
|
|
18
|
+
}
|
|
19
|
+
export declare function createKernelFacade(config: KernelFacadeConfig): KernelFacadeController;
|
|
20
|
+
export type FacadeParams = {
|
|
21
|
+
adapter: KernelClientAdapter;
|
|
22
|
+
getCredential: () => string;
|
|
23
|
+
url: string;
|
|
24
|
+
/** Explicit mint subject. When omitted, the authenticated caller is resolved via `whoami`. */
|
|
25
|
+
mintIdentity?: string;
|
|
26
|
+
};
|
|
27
|
+
/**
|
|
28
|
+
* Bind the unified kernel surface to a credential thunk and attach the shell
|
|
29
|
+
* extras. The bound view IS the kernel surface (`.get/.node/.query/.mutate/
|
|
30
|
+
* .call/…` plus the `auth` control plane), credential-bound via `getCredential`
|
|
31
|
+
* (invoked per dispatch); `mintDelegation`/`authToken`/`url` layer on top as
|
|
32
|
+
* the deprecated iframe-ABI aliases over the view's `auth` namespace.
|
|
33
|
+
*/
|
|
34
|
+
export declare function buildCredentialFacade(params: FacadeParams): KernelFacadeController;
|
|
35
|
+
//# sourceMappingURL=credential.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"credential.d.ts","sourceRoot":"","sources":["../../src/kernel/credential.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,UAAU,CAAA;AAC5C,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,WAAW,CAAA;AAEpD,MAAM,MAAM,kBAAkB,GAAG;IAC/B,OAAO,EAAE,mBAAmB,CAAA;IAC5B,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,aAAa,CAAC,EAAE,MAAM,MAAM,CAAA;IAC5B,gEAAgE;IAChE,GAAG,EAAE,MAAM,CAAA;IACX;;;;OAIG;IACH,YAAY,CAAC,EAAE,MAAM,CAAA;CACtB,CAAA;AAED,MAAM,WAAW,sBAAuB,SAAQ,YAAY;IAC1D,OAAO,IAAI,IAAI,CAAA;CAChB;AAED,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,kBAAkB,GAAG,sBAAsB,CAerF;AAED,MAAM,MAAM,YAAY,GAAG;IACzB,OAAO,EAAE,mBAAmB,CAAA;IAC5B,aAAa,EAAE,MAAM,MAAM,CAAA;IAC3B,GAAG,EAAE,MAAM,CAAA;IACX,8FAA8F;IAC9F,YAAY,CAAC,EAAE,MAAM,CAAA;CACtB,CAAA;AAED;;;;;;GAMG;AACH,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,YAAY,GAAG,sBAAsB,CAwBlF"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
export function createKernelFacade(config) {
|
|
2
|
+
const getCredential = config.getCredential ??
|
|
3
|
+
(() => {
|
|
4
|
+
if (config.credential === undefined) {
|
|
5
|
+
throw new Error('KernelFacade requires credential or getCredential');
|
|
6
|
+
}
|
|
7
|
+
return config.credential;
|
|
8
|
+
});
|
|
9
|
+
return buildCredentialFacade({
|
|
10
|
+
adapter: config.adapter,
|
|
11
|
+
getCredential,
|
|
12
|
+
url: config.url,
|
|
13
|
+
mintIdentity: config.mintIdentity,
|
|
14
|
+
});
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Bind the unified kernel surface to a credential thunk and attach the shell
|
|
18
|
+
* extras. The bound view IS the kernel surface (`.get/.node/.query/.mutate/
|
|
19
|
+
* .call/…` plus the `auth` control plane), credential-bound via `getCredential`
|
|
20
|
+
* (invoked per dispatch); `mintDelegation`/`authToken`/`url` layer on top as
|
|
21
|
+
* the deprecated iframe-ABI aliases over the view's `auth` namespace.
|
|
22
|
+
*/
|
|
23
|
+
export function buildCredentialFacade(params) {
|
|
24
|
+
const { adapter, getCredential, mintIdentity, url } = params;
|
|
25
|
+
const view = adapter.boundView(getCredential);
|
|
26
|
+
// @deprecated iframe ABI — use `shell.kernel.auth.mint()`. Mints an identity
|
|
27
|
+
// credential for the pinned `mintIdentity`, else the whoami-resolved caller.
|
|
28
|
+
// No implicit `__system__` fallback — an unresolved principal throws rather
|
|
29
|
+
// than silently minting a child credential as kernel root.
|
|
30
|
+
async function mintDelegation() {
|
|
31
|
+
return view.auth.mint(mintIdentity !== undefined ? { subject: mintIdentity } : undefined);
|
|
32
|
+
}
|
|
33
|
+
// @deprecated iframe ABI — use `shell.kernel.auth.credential()`. Shell
|
|
34
|
+
// credentials are JWT strings; decode the `Uint8Array` arm defensively.
|
|
35
|
+
function authToken() {
|
|
36
|
+
const credential = view.auth.credential();
|
|
37
|
+
return typeof credential === 'string' ? credential : new TextDecoder().decode(credential);
|
|
38
|
+
}
|
|
39
|
+
function dispose() {
|
|
40
|
+
// adapter lifetime is owned by the caller
|
|
41
|
+
}
|
|
42
|
+
return Object.assign(view, { mintDelegation, authToken, url, dispose });
|
|
43
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { KernelFacadeController } from './credential';
|
|
2
|
+
import type { DelegationToken } from './delegation/token';
|
|
3
|
+
import type { KernelClientAdapter } from './session';
|
|
4
|
+
export type DelegationKernelFacadeConfig = {
|
|
5
|
+
adapter: KernelClientAdapter;
|
|
6
|
+
initialToken: DelegationToken;
|
|
7
|
+
url: string;
|
|
8
|
+
onTokenChange?: (token: DelegationToken) => void;
|
|
9
|
+
mintIdentity?: string;
|
|
10
|
+
};
|
|
11
|
+
export interface DelegationKernelFacadeController extends KernelFacadeController {
|
|
12
|
+
token(): DelegationToken;
|
|
13
|
+
setToken(next: DelegationToken): void;
|
|
14
|
+
}
|
|
15
|
+
/** The sandboxed-mode kernel: bound to a delegation token the parent refreshes. */
|
|
16
|
+
export declare function createDelegationKernelFacade(config: DelegationKernelFacadeConfig): DelegationKernelFacadeController;
|
|
17
|
+
//# sourceMappingURL=delegated.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"delegated.d.ts","sourceRoot":"","sources":["../../src/kernel/delegated.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,cAAc,CAAA;AAC1D,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAA;AACzD,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,WAAW,CAAA;AAIpD,MAAM,MAAM,4BAA4B,GAAG;IACzC,OAAO,EAAE,mBAAmB,CAAA;IAC5B,YAAY,EAAE,eAAe,CAAA;IAC7B,GAAG,EAAE,MAAM,CAAA;IACX,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,eAAe,KAAK,IAAI,CAAA;IAChD,YAAY,CAAC,EAAE,MAAM,CAAA;CACtB,CAAA;AAED,MAAM,WAAW,gCAAiC,SAAQ,sBAAsB;IAC9E,KAAK,IAAI,eAAe,CAAA;IACxB,QAAQ,CAAC,IAAI,EAAE,eAAe,GAAG,IAAI,CAAA;CACtC;AAED,mFAAmF;AACnF,wBAAgB,4BAA4B,CAC1C,MAAM,EAAE,4BAA4B,GACnC,gCAAgC,CA0BlC"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { buildCredentialFacade } from './credential';
|
|
2
|
+
/** The sandboxed-mode kernel: bound to a delegation token the parent refreshes. */
|
|
3
|
+
export function createDelegationKernelFacade(config) {
|
|
4
|
+
let token = config.initialToken;
|
|
5
|
+
const base = buildCredentialFacade({
|
|
6
|
+
adapter: config.adapter,
|
|
7
|
+
getCredential: () => token.credential,
|
|
8
|
+
url: config.url,
|
|
9
|
+
mintIdentity: config.mintIdentity,
|
|
10
|
+
});
|
|
11
|
+
return {
|
|
12
|
+
...base,
|
|
13
|
+
token() {
|
|
14
|
+
return token;
|
|
15
|
+
},
|
|
16
|
+
setToken(next) {
|
|
17
|
+
if (next.credential === token.credential && next.expiresAt === token.expiresAt)
|
|
18
|
+
return;
|
|
19
|
+
token = next;
|
|
20
|
+
config.onTokenChange?.(next);
|
|
21
|
+
},
|
|
22
|
+
// The delegation facade owns its adapter exclusively (created per child in
|
|
23
|
+
// `performChildInit`), so disposing it must tear the adapter down — unlike
|
|
24
|
+
// the standalone facade, where the caller owns the adapter's lifetime.
|
|
25
|
+
dispose() {
|
|
26
|
+
config.adapter.disconnect();
|
|
27
|
+
},
|
|
28
|
+
};
|
|
29
|
+
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { DelegationToken } from '
|
|
1
|
+
import type { DelegationToken } from './token';
|
|
2
2
|
export type TokenRefreshConfig = {
|
|
3
3
|
readonly token: () => DelegationToken;
|
|
4
4
|
readonly setToken: (next: DelegationToken) => void;
|
|
@@ -16,4 +16,4 @@ export interface TokenRefresher {
|
|
|
16
16
|
forceRefreshNow(): Promise<void>;
|
|
17
17
|
}
|
|
18
18
|
export declare function createTokenRefresher(config: TokenRefreshConfig): TokenRefresher;
|
|
19
|
-
//# sourceMappingURL=
|
|
19
|
+
//# sourceMappingURL=refresh.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"refresh.d.ts","sourceRoot":"","sources":["../../../src/kernel/delegation/refresh.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,SAAS,CAAA;AAI9C,MAAM,MAAM,kBAAkB,GAAG;IAC/B,QAAQ,CAAC,KAAK,EAAE,MAAM,eAAe,CAAA;IACrC,QAAQ,CAAC,QAAQ,EAAE,CAAC,IAAI,EAAE,eAAe,KAAK,IAAI,CAAA;IAClD,QAAQ,CAAC,IAAI,EAAE,MAAM,OAAO,CAAC;QAAE,UAAU,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAA;KAAE,CAAC,CAAA;IACvE,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAA;IAC3B,QAAQ,CAAC,SAAS,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,IAAI,CAAA;IAC7C,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,MAAM,CAAA;CAC5B,CAAA;AAED,MAAM,WAAW,cAAc;IAC7B,KAAK,IAAI,IAAI,CAAA;IACb,IAAI,IAAI,IAAI,CAAA;IACZ,eAAe,IAAI,OAAO,CAAC,IAAI,CAAC,CAAA;CACjC;AAID,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,kBAAkB,GAAG,cAAc,CAoD/E"}
|
|
@@ -12,4 +12,4 @@ export type TokenState = 'fresh' | 'expiring' | 'expired' | 'refreshing' | 'fail
|
|
|
12
12
|
export declare const REFRESH_WINDOW_MS = 120000;
|
|
13
13
|
export declare function stateOf(token: DelegationToken, now?: number): TokenState;
|
|
14
14
|
export declare function isExpired(token: DelegationToken, now?: number): boolean;
|
|
15
|
-
//# sourceMappingURL=
|
|
15
|
+
//# sourceMappingURL=token.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"token.d.ts","sourceRoot":"","sources":["../../../src/kernel/delegation/token.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,eAAe,GAAG;IAC5B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAA;CAC5B,CAAA;AAED,MAAM,MAAM,eAAe,GAAG;IAC5B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAA;IAC3B,QAAQ,CAAC,KAAK,EAAE,eAAe,CAAA;IAC/B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAA;IACzB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAA;CAC3B,CAAA;AAED,MAAM,MAAM,UAAU,GAAG,OAAO,GAAG,UAAU,GAAG,SAAS,GAAG,YAAY,GAAG,QAAQ,CAAA;AAEnF,kEAAkE;AAClE,eAAO,MAAM,iBAAiB,SAAU,CAAA;AAExC,wBAAgB,OAAO,CAAC,KAAK,EAAE,eAAe,EAAE,GAAG,SAAa,GAAG,UAAU,CAI5E;AAED,wBAAgB,SAAS,CAAC,KAAK,EAAE,eAAe,EAAE,GAAG,SAAa,GAAG,OAAO,CAE3E"}
|
|
@@ -1,10 +1,12 @@
|
|
|
1
|
-
import { type CallOptions, type CredentialInput, type FunctionSchema } from '@astrale-os/kernel-client';
|
|
1
|
+
import { type CallOptions, type CredentialInput, type FnMap, type FunctionSchema } from '@astrale-os/kernel-client';
|
|
2
|
+
import { type BoundClientSessionView } from '@astrale-os/kernel-client/session';
|
|
3
|
+
type AnyFnMap = FnMap;
|
|
2
4
|
/**
|
|
3
5
|
* Low-level kernel adapter — wraps a `ClientSession` (the post-v2 orchestration
|
|
4
6
|
* layer above `KernelClient`).
|
|
5
7
|
*
|
|
6
|
-
* Methods take an explicit credential. The
|
|
7
|
-
*
|
|
8
|
+
* Methods take an explicit credential. The credential facades manage which
|
|
9
|
+
* credential to use.
|
|
8
10
|
*
|
|
9
11
|
* Remote-domain redirects are followed transparently: when the kernel
|
|
10
12
|
* responds with a `redirect` result (pointing at an external worker URL),
|
|
@@ -16,6 +18,14 @@ import { type CallOptions, type CredentialInput, type FunctionSchema } from '@as
|
|
|
16
18
|
*/
|
|
17
19
|
export type KernelClientAdapter = {
|
|
18
20
|
call(method: string, params: unknown, credential: CredentialInput, opts?: CallOptions): Promise<unknown>;
|
|
21
|
+
/**
|
|
22
|
+
* Credential-bound view over the underlying `ClientSession` — the flattened
|
|
23
|
+
* `BoundClientSessionView` surface (`.get/.node/.children/.query/.mutate/
|
|
24
|
+
* .createNode/…` graph sugar beside `.call/.stream/.as/…`). `getCredential`
|
|
25
|
+
* is a thunk invoked per dispatch, so the view tracks the active identity the
|
|
26
|
+
* same way the per-call `credential` injection did.
|
|
27
|
+
*/
|
|
28
|
+
boundView(getCredential: () => CredentialInput): BoundClientSessionView<AnyFnMap>;
|
|
19
29
|
load(schemas: FunctionSchema[]): void;
|
|
20
30
|
disconnect(): void;
|
|
21
31
|
readonly url: string;
|
|
@@ -33,14 +43,6 @@ export type CreateKernelClientAdapterOpts = {
|
|
|
33
43
|
* with `Credential audience mismatch`.
|
|
34
44
|
*/
|
|
35
45
|
getCredential?: () => CredentialInput;
|
|
36
|
-
/**
|
|
37
|
-
* Explicit identity node/path to use as the delegation mint subject. When
|
|
38
|
-
* omitted, the authenticated caller is resolved via `whoami` (so a cookie-fronted
|
|
39
|
-
* SPA mints as the logged-in user). Set this only to pin a subject; if set it
|
|
40
|
-
* MUST match the principal `getCredential()` authenticates as, or
|
|
41
|
-
* `mintDelegationCredential`'s self-invariant rejects the mint.
|
|
42
|
-
*/
|
|
43
|
-
mintIdentity?: string;
|
|
44
46
|
/**
|
|
45
47
|
* Wire-layer `fetch` shim, forwarded to the underlying `KernelClient`s.
|
|
46
48
|
* Lets a same-origin SPA inject `credentials:'include'` + refresh-on-401 so
|
|
@@ -50,4 +52,5 @@ export type CreateKernelClientAdapterOpts = {
|
|
|
50
52
|
fetch?: typeof fetch;
|
|
51
53
|
};
|
|
52
54
|
export declare function createKernelClientAdapter(opts: CreateKernelClientAdapterOpts): KernelClientAdapter;
|
|
53
|
-
|
|
55
|
+
export {};
|
|
56
|
+
//# sourceMappingURL=session.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"session.d.ts","sourceRoot":"","sources":["../../src/kernel/session.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,WAAW,EAChB,KAAK,eAAe,EACpB,KAAK,KAAK,EACV,KAAK,cAAc,EACpB,MAAM,2BAA2B,CAAA;AAClC,OAAO,EACL,KAAK,sBAAsB,EAI5B,MAAM,mCAAmC,CAAA;AAG1C,KAAK,QAAQ,GAAG,KAAK,CAAA;AAErB;;;;;;;;;;;;;;GAcG;AACH,MAAM,MAAM,mBAAmB,GAAG;IAChC,IAAI,CACF,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,OAAO,EACf,UAAU,EAAE,eAAe,EAC3B,IAAI,CAAC,EAAE,WAAW,GACjB,OAAO,CAAC,OAAO,CAAC,CAAA;IACnB;;;;;;OAMG;IACH,SAAS,CAAC,aAAa,EAAE,MAAM,eAAe,GAAG,sBAAsB,CAAC,QAAQ,CAAC,CAAA;IACjF,IAAI,CAAC,OAAO,EAAE,cAAc,EAAE,GAAG,IAAI,CAAA;IACrC,UAAU,IAAI,IAAI,CAAA;IAClB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAA;CACrB,CAAA;AAED,MAAM,MAAM,6BAA6B,GAAG;IAC1C,GAAG,EAAE,MAAM,CAAA;IACX,MAAM,CAAC,EAAE,cAAc,EAAE,CAAA;IACzB,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB;;;;;;;OAOG;IACH,aAAa,CAAC,EAAE,MAAM,eAAe,CAAA;IACrC;;;;;OAKG;IACH,KAAK,CAAC,EAAE,OAAO,KAAK,CAAA;CACrB,CAAA;AAED,wBAAgB,yBAAyB,CACvC,IAAI,EAAE,6BAA6B,GAClC,mBAAmB,CAuDrB"}
|
|
@@ -1,7 +1,5 @@
|
|
|
1
1
|
import {} from '@astrale-os/kernel-client';
|
|
2
|
-
import { ClientSession } from '@astrale-os/kernel-client/session';
|
|
3
|
-
import { identityMethod } from '../domain/identity/path';
|
|
4
|
-
import { createSelfResolver, WHOAMI_PATH } from '../domain/identity/resolve-self';
|
|
2
|
+
import { ClientSession, delegationMintVia, } from '@astrale-os/kernel-client/session';
|
|
5
3
|
export function createKernelClientAdapter(opts) {
|
|
6
4
|
let session = null;
|
|
7
5
|
const config = {
|
|
@@ -18,27 +16,24 @@ export function createKernelClientAdapter(opts) {
|
|
|
18
16
|
config.fetch = opts.fetch;
|
|
19
17
|
if (opts.getCredential) {
|
|
20
18
|
const getCred = opts.getCredential;
|
|
21
|
-
|
|
22
|
-
|
|
19
|
+
// Cross-origin redirects (kernel → worker) mint a fresh worker-scoped
|
|
20
|
+
// delegation from the active identity — the blessed self-mint adapter over
|
|
21
|
+
// `auth.delegate`, with the `skipDelegation` recursion guard baked in.
|
|
23
22
|
config.delegation = {
|
|
24
|
-
mint:
|
|
23
|
+
mint: delegationMintVia(() => {
|
|
25
24
|
if (!session)
|
|
26
25
|
throw new Error('ClientSession not initialised');
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
(await resolveSelf(() => s.call(WHOAMI_PATH, {}, { credential: getCred(), skipDelegation: true })));
|
|
30
|
-
const result = await s.call(identityMethod(subject, 'mintDelegationCredential'), { audience, delegation, ttl: 3600 }, { credential: getCred(), skipDelegation: true });
|
|
31
|
-
if (typeof result !== 'string') {
|
|
32
|
-
throw new Error(`mintDelegationCredential returned non-string: ${typeof result}`);
|
|
33
|
-
}
|
|
34
|
-
return { credential: result, ttl: 3600 };
|
|
35
|
-
},
|
|
26
|
+
return session;
|
|
27
|
+
}, getCred),
|
|
36
28
|
};
|
|
37
29
|
}
|
|
38
30
|
session = new ClientSession(config);
|
|
39
31
|
const ready = session;
|
|
40
32
|
return {
|
|
41
33
|
url: opts.url,
|
|
34
|
+
boundView(getCredential) {
|
|
35
|
+
return ready.as(getCredential);
|
|
36
|
+
},
|
|
42
37
|
call(method, params, credential, callOpts) {
|
|
43
38
|
const sessionOpts = { credential };
|
|
44
39
|
if (callOpts?.timeout !== undefined)
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Control message registry — extensible via declaration merging.
|
|
3
|
+
*/
|
|
4
|
+
export interface CtrlRegistry {
|
|
5
|
+
handshake: {
|
|
6
|
+
data: {
|
|
7
|
+
delegationToken: string;
|
|
8
|
+
tokenExpiresAt: number;
|
|
9
|
+
windowId: string;
|
|
10
|
+
kernelUrl: string;
|
|
11
|
+
functionId: string;
|
|
12
|
+
targetNodeId?: string;
|
|
13
|
+
mintIdentity?: string;
|
|
14
|
+
};
|
|
15
|
+
};
|
|
16
|
+
handshakeAck: {
|
|
17
|
+
data: {
|
|
18
|
+
windowId: string;
|
|
19
|
+
};
|
|
20
|
+
};
|
|
21
|
+
tokenRefresh: {
|
|
22
|
+
data: {
|
|
23
|
+
delegationToken: string;
|
|
24
|
+
tokenExpiresAt: number;
|
|
25
|
+
};
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
export type CtrlMessage<K extends keyof CtrlRegistry = keyof CtrlRegistry> = {
|
|
29
|
+
readonly type: 'ctrl';
|
|
30
|
+
readonly version: 1;
|
|
31
|
+
readonly action: K;
|
|
32
|
+
readonly data: CtrlRegistry[K]['data'];
|
|
33
|
+
};
|
|
34
|
+
//# sourceMappingURL=ctrl.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ctrl.d.ts","sourceRoot":"","sources":["../../src/message/ctrl.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B,SAAS,EAAE;QACT,IAAI,EAAE;YACJ,eAAe,EAAE,MAAM,CAAA;YACvB,cAAc,EAAE,MAAM,CAAA;YACtB,QAAQ,EAAE,MAAM,CAAA;YAChB,SAAS,EAAE,MAAM,CAAA;YACjB,UAAU,EAAE,MAAM,CAAA;YAClB,YAAY,CAAC,EAAE,MAAM,CAAA;YACrB,YAAY,CAAC,EAAE,MAAM,CAAA;SACtB,CAAA;KACF,CAAA;IACD,YAAY,EAAE;QAAE,IAAI,EAAE;YAAE,QAAQ,EAAE,MAAM,CAAA;SAAE,CAAA;KAAE,CAAA;IAC5C,YAAY,EAAE;QAAE,IAAI,EAAE;YAAE,eAAe,EAAE,MAAM,CAAC;YAAC,cAAc,EAAE,MAAM,CAAA;SAAE,CAAA;KAAE,CAAA;CAC5E;AAED,MAAM,MAAM,WAAW,CAAC,CAAC,SAAS,MAAM,YAAY,GAAG,MAAM,YAAY,IAAI;IAC3E,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,OAAO,EAAE,CAAC,CAAA;IACnB,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAA;IAClB,QAAQ,CAAC,IAAI,EAAE,YAAY,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAA;CACvC,CAAA"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export type ErrorCode = 'HANDSHAKE_TIMEOUT' | 'ORIGIN_MISMATCH' | 'WINDOW_UNAVAILABLE' | 'UNSUPPORTED_VERSION' | 'INTENT_NOT_ALLOWED' | 'DELIVERY_FAILED' | 'TOKEN_REFRESH_FAILED' | 'NO_VIEW_AVAILABLE';
|
|
2
|
+
export type ErrorMessage = {
|
|
3
|
+
readonly type: 'error';
|
|
4
|
+
readonly version: 1;
|
|
5
|
+
readonly code: ErrorCode;
|
|
6
|
+
readonly message: string;
|
|
7
|
+
readonly context?: unknown;
|
|
8
|
+
};
|
|
9
|
+
//# sourceMappingURL=error.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"error.d.ts","sourceRoot":"","sources":["../../src/message/error.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,SAAS,GACjB,mBAAmB,GACnB,iBAAiB,GACjB,oBAAoB,GACpB,qBAAqB,GACrB,oBAAoB,GACpB,iBAAiB,GACjB,sBAAsB,GACtB,mBAAmB,CAAA;AAEvB,MAAM,MAAM,YAAY,GAAG;IACzB,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAA;IACtB,QAAQ,CAAC,OAAO,EAAE,CAAC,CAAA;IACnB,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAA;IACxB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;IACxB,QAAQ,CAAC,OAAO,CAAC,EAAE,OAAO,CAAA;CAC3B,CAAA"}
|
|
@@ -18,4 +18,4 @@ export type InitResponseMessage = {
|
|
|
18
18
|
};
|
|
19
19
|
export declare function isInitRequest(value: unknown): value is InitRequestMessage;
|
|
20
20
|
export declare function isInitResponse(value: unknown): value is InitResponseMessage;
|
|
21
|
-
//# sourceMappingURL=
|
|
21
|
+
//# sourceMappingURL=init.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../../src/message/init.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,eAAO,MAAM,iBAAiB,+BAA+B,CAAA;AAC7D,eAAO,MAAM,kBAAkB,gCAAgC,CAAA;AAE/D,MAAM,MAAM,kBAAkB,GAAG;IAC/B,QAAQ,CAAC,IAAI,EAAE,OAAO,iBAAiB,CAAA;IACvC,QAAQ,CAAC,OAAO,EAAE,CAAC,CAAA;CACpB,CAAA;AAED,MAAM,MAAM,mBAAmB,GAAG;IAChC,QAAQ,CAAC,IAAI,EAAE,OAAO,kBAAkB,CAAA;IACxC,QAAQ,CAAC,OAAO,EAAE,CAAC,CAAA;IACnB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAA;CAC1B,CAAA;AAED,wBAAgB,aAAa,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,kBAAkB,CAMzE;AAED,wBAAgB,cAAc,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,mBAAmB,CAM3E"}
|
|
@@ -6,6 +6,10 @@ export interface ViewRef {
|
|
|
6
6
|
/**
|
|
7
7
|
* Intent registry — extensible via declaration merging.
|
|
8
8
|
*
|
|
9
|
+
* An entry is EITHER `{ payload; reply }` (the reply-typed convention) OR a bare
|
|
10
|
+
* payload type (legacy). Read entries through {@link PayloadOf} / {@link ReplyOf}
|
|
11
|
+
* — never index `[K]['payload']` directly, so bare augmentations keep compiling.
|
|
12
|
+
*
|
|
9
13
|
* Consumers extend via:
|
|
10
14
|
* declare module '@astrale-os/shell' {
|
|
11
15
|
* interface IntentRegistry { ... }
|
|
@@ -17,7 +21,7 @@ export interface IntentRegistry {
|
|
|
17
21
|
nodeId: string;
|
|
18
22
|
viewId?: string;
|
|
19
23
|
};
|
|
20
|
-
|
|
24
|
+
reply: {
|
|
21
25
|
windowId: string;
|
|
22
26
|
};
|
|
23
27
|
};
|
|
@@ -25,33 +29,33 @@ export interface IntentRegistry {
|
|
|
25
29
|
payload: {
|
|
26
30
|
windowId: string;
|
|
27
31
|
};
|
|
28
|
-
|
|
32
|
+
reply: void;
|
|
29
33
|
};
|
|
30
34
|
focus: {
|
|
31
35
|
payload: {
|
|
32
36
|
nodeId: string;
|
|
33
37
|
};
|
|
34
|
-
|
|
38
|
+
reply: void;
|
|
35
39
|
};
|
|
36
40
|
willClose: {
|
|
37
41
|
payload: Record<string, never>;
|
|
38
|
-
|
|
42
|
+
reply: void;
|
|
39
43
|
};
|
|
40
44
|
closeAck: {
|
|
41
45
|
payload: Record<string, never>;
|
|
42
|
-
|
|
46
|
+
reply: void;
|
|
43
47
|
};
|
|
44
48
|
closeRefuse: {
|
|
45
49
|
payload: {
|
|
46
50
|
reason: string;
|
|
47
51
|
};
|
|
48
|
-
|
|
52
|
+
reply: void;
|
|
49
53
|
};
|
|
50
54
|
pickView: {
|
|
51
55
|
payload: {
|
|
52
56
|
views: ViewRef[];
|
|
53
57
|
};
|
|
54
|
-
|
|
58
|
+
reply: {
|
|
55
59
|
viewId: string;
|
|
56
60
|
};
|
|
57
61
|
};
|
|
@@ -60,7 +64,7 @@ export interface IntentRegistry {
|
|
|
60
64
|
data: unknown;
|
|
61
65
|
sourceIntent: string;
|
|
62
66
|
};
|
|
63
|
-
|
|
67
|
+
reply: void;
|
|
64
68
|
};
|
|
65
69
|
/**
|
|
66
70
|
* Hot-swap — parent pushes a new target node to an already-mounted view
|
|
@@ -72,7 +76,7 @@ export interface IntentRegistry {
|
|
|
72
76
|
payload: {
|
|
73
77
|
nodeId: string;
|
|
74
78
|
};
|
|
75
|
-
|
|
79
|
+
reply: void;
|
|
76
80
|
};
|
|
77
81
|
/**
|
|
78
82
|
* Child → parent: a view asks the user to grant `perms` (a permission
|
|
@@ -82,7 +86,7 @@ export interface IntentRegistry {
|
|
|
82
86
|
* `@<id>`. The root shell (GUI) surfaces a modal, computes the delta vs.
|
|
83
87
|
* what the subject already holds, and — on approval — grants only the
|
|
84
88
|
* missing bits under the GUI user's own credential. `reason` is shown to
|
|
85
|
-
* the user. `
|
|
89
|
+
* the user. `reply.perms` is the bitmask actually granted (0 if
|
|
86
90
|
* declined / nothing was missing).
|
|
87
91
|
*
|
|
88
92
|
* Reaches a handler only from a view mounted as a DIRECT child of the root
|
|
@@ -95,7 +99,7 @@ export interface IntentRegistry {
|
|
|
95
99
|
perms: number;
|
|
96
100
|
reason?: string;
|
|
97
101
|
};
|
|
98
|
-
|
|
102
|
+
reply: {
|
|
99
103
|
granted: boolean;
|
|
100
104
|
perms: number;
|
|
101
105
|
};
|
|
@@ -112,34 +116,38 @@ export interface IntentRegistry {
|
|
|
112
116
|
correlationId: string;
|
|
113
117
|
result: unknown;
|
|
114
118
|
};
|
|
115
|
-
|
|
119
|
+
reply: void;
|
|
116
120
|
};
|
|
117
121
|
}
|
|
118
122
|
/**
|
|
119
|
-
*
|
|
123
|
+
* Payload type for intent `K`. A `{ payload; reply }` entry projects its
|
|
124
|
+
* `payload`; a bare-payload (legacy) entry IS the payload. Distributes over `K`
|
|
125
|
+
* (the outer `extends` makes `K` naked) so `PayloadOf<keyof IntentRegistry>` is
|
|
126
|
+
* the union of per-key payloads, not the union of entries.
|
|
120
127
|
*/
|
|
121
|
-
export
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
tokenRefresh: {
|
|
139
|
-
data: {
|
|
140
|
-
delegationToken: string;
|
|
141
|
-
tokenExpiresAt: number;
|
|
142
|
-
};
|
|
128
|
+
export type PayloadOf<K extends keyof IntentRegistry> = K extends keyof IntentRegistry ? IntentRegistry[K] extends {
|
|
129
|
+
payload: infer P;
|
|
130
|
+
} ? P : IntentRegistry[K] : never;
|
|
131
|
+
/**
|
|
132
|
+
* Reply type for intent `K` — the value a handler sends back through
|
|
133
|
+
* `ctx.reply` and a `requestIntent`/`useSendIntent` caller awaits. A
|
|
134
|
+
* `{ reply }` entry projects its `reply`; every other entry is `void`.
|
|
135
|
+
* Distributes over `K` (see {@link PayloadOf}).
|
|
136
|
+
*/
|
|
137
|
+
export type ReplyOf<K extends keyof IntentRegistry> = K extends keyof IntentRegistry ? IntentRegistry[K] extends {
|
|
138
|
+
reply: infer R;
|
|
139
|
+
} ? R : void : never;
|
|
140
|
+
export type IntentEnvelope<K extends keyof IntentRegistry = keyof IntentRegistry> = {
|
|
141
|
+
readonly name: K;
|
|
142
|
+
readonly payload: PayloadOf<K>;
|
|
143
|
+
readonly sender: {
|
|
144
|
+
readonly windowId: string;
|
|
143
145
|
};
|
|
144
|
-
|
|
145
|
-
|
|
146
|
+
readonly correlationId?: string;
|
|
147
|
+
};
|
|
148
|
+
export type IntentMessage<K extends keyof IntentRegistry = keyof IntentRegistry> = {
|
|
149
|
+
readonly type: 'intent';
|
|
150
|
+
readonly version: 1;
|
|
151
|
+
readonly envelope: IntentEnvelope<K>;
|
|
152
|
+
};
|
|
153
|
+
//# sourceMappingURL=intent.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"intent.d.ts","sourceRoot":"","sources":["../../src/message/intent.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { CtrlMessage } from './ctrl';
|
|
2
|
+
import type { ErrorMessage } from './error';
|
|
3
|
+
import type { IntentMessage } from './intent';
|
|
4
|
+
export type ShellMessage = IntentMessage | CtrlMessage | ErrorMessage;
|
|
5
|
+
export type MessageHandler<M extends ShellMessage = ShellMessage> = (message: M) => void;
|
|
6
|
+
export type MessageType = ShellMessage['type'];
|
|
7
|
+
export type MessageOf<T extends MessageType> = Extract<ShellMessage, {
|
|
8
|
+
type: T;
|
|
9
|
+
}>;
|
|
10
|
+
//# sourceMappingURL=message.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"message.d.ts","sourceRoot":"","sources":["../../src/message/message.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,QAAQ,CAAA;AACzC,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,SAAS,CAAA;AAC3C,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,UAAU,CAAA;AAE7C,MAAM,MAAM,YAAY,GAAG,aAAa,GAAG,WAAW,GAAG,YAAY,CAAA;AAErE,MAAM,MAAM,cAAc,CAAC,CAAC,SAAS,YAAY,GAAG,YAAY,IAAI,CAAC,OAAO,EAAE,CAAC,KAAK,IAAI,CAAA;AAExF,MAAM,MAAM,WAAW,GAAG,YAAY,CAAC,MAAM,CAAC,CAAA;AAE9C,MAAM,MAAM,SAAS,CAAC,CAAC,SAAS,WAAW,IAAI,OAAO,CAAC,YAAY,EAAE;IAAE,IAAI,EAAE,CAAC,CAAA;CAAE,CAAC,CAAA"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { PayloadOf, ReplyOf } from '../message/intent';
|
|
2
|
+
import type { Shell } from './shell';
|
|
3
|
+
/**
|
|
4
|
+
* View SDK convenience: ask the user (via the root shell) to grant `perms` on
|
|
5
|
+
* `node` to `identity`. Resolves with the bitmask actually granted (0 if the
|
|
6
|
+
* user declined or there was no parent to ask). The view typically passes its
|
|
7
|
+
* own identity (from `whoami`) as `identity`.
|
|
8
|
+
*/
|
|
9
|
+
export declare function requestAccess(shell: Shell, opts: PayloadOf<'requestAccess'>): Promise<ReplyOf<'requestAccess'>>;
|
|
10
|
+
//# sourceMappingURL=access.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"access.d.ts","sourceRoot":"","sources":["../../src/shell/access.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,SAAS,EAAE,OAAO,EAAE,MAAM,mBAAmB,CAAA;AAC3D,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,SAAS,CAAA;AAIpC;;;;;GAKG;AACH,wBAAgB,aAAa,CAC3B,KAAK,EAAE,KAAK,EACZ,IAAI,EAAE,SAAS,CAAC,eAAe,CAAC,GAC/B,OAAO,CAAC,OAAO,CAAC,eAAe,CAAC,CAAC,CASnC"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { NO_PERMS } from '@astrale-os/kernel-core/permissions';
|
|
2
|
+
import { requestIntent } from '../intent/request';
|
|
3
|
+
/**
|
|
4
|
+
* View SDK convenience: ask the user (via the root shell) to grant `perms` on
|
|
5
|
+
* `node` to `identity`. Resolves with the bitmask actually granted (0 if the
|
|
6
|
+
* user declined or there was no parent to ask). The view typically passes its
|
|
7
|
+
* own identity (from `whoami`) as `identity`.
|
|
8
|
+
*/
|
|
9
|
+
export function requestAccess(shell, opts) {
|
|
10
|
+
if (!shell.parent)
|
|
11
|
+
return Promise.resolve({ granted: false, perms: NO_PERMS });
|
|
12
|
+
// A sandboxed shell's `parent` is a proxy that throws until `init()` resolves;
|
|
13
|
+
// honour the documented "no parent to ask" fallback instead of surfacing that
|
|
14
|
+
// opaque rejection to the caller.
|
|
15
|
+
return requestIntent(shell.parent, 'requestAccess', opts).catch(() => ({
|
|
16
|
+
granted: false,
|
|
17
|
+
perms: NO_PERMS,
|
|
18
|
+
}));
|
|
19
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import type { ChildrenChannelController } from '../channel/children';
|
|
2
|
+
import type { MessageObserver } from '../channel/observer';
|
|
3
|
+
import type { ParentChannel } from '../channel/parent';
|
|
4
|
+
import type { IntentPipeline } from '../intent/pipeline';
|
|
5
|
+
import type { LocalIntentHandler } from '../intent/router';
|
|
6
|
+
import type { KernelClient } from '../kernel/client';
|
|
7
|
+
import type { IntentRegistry } from '../message/intent';
|
|
8
|
+
import type { LifecycleController } from '../window/lifecycle/states';
|
|
9
|
+
import type { MountController } from '../window/mount/mount';
|
|
10
|
+
import type { Window } from '../window/window';
|
|
11
|
+
import type { Shell } from './shell';
|
|
12
|
+
export type FacadeDeps = {
|
|
13
|
+
parent: ParentChannel | null;
|
|
14
|
+
childrenChannel: ChildrenChannelController;
|
|
15
|
+
kernel: KernelClient;
|
|
16
|
+
pipeline: IntentPipeline;
|
|
17
|
+
observer: MessageObserver;
|
|
18
|
+
lifecycle: LifecycleController;
|
|
19
|
+
windows: Map<string, Window>;
|
|
20
|
+
getMountController: () => MountController;
|
|
21
|
+
onIntent: <K extends keyof IntentRegistry>(name: K, handler: LocalIntentHandler<K>) => () => void;
|
|
22
|
+
targetNodeId?: () => string | undefined;
|
|
23
|
+
init?: () => Promise<void>;
|
|
24
|
+
onDispose: () => Promise<void>;
|
|
25
|
+
};
|
|
26
|
+
/** Assemble the Shell object shared by both modes from their wired parts. */
|
|
27
|
+
export declare function buildShellFacade(deps: FacadeDeps): Shell;
|
|
28
|
+
//# sourceMappingURL=build.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"build.d.ts","sourceRoot":"","sources":["../../src/shell/build.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,qBAAqB,CAAA;AACpE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAA;AAC1D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAA;AACtD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAA;AACxD,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAA;AAC1D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAA;AACpD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAA;AACvD,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,4BAA4B,CAAA;AACrE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAA;AAC5D,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAA;AAC9C,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,SAAS,CAAA;AAIpC,MAAM,MAAM,UAAU,GAAG;IACvB,MAAM,EAAE,aAAa,GAAG,IAAI,CAAA;IAC5B,eAAe,EAAE,yBAAyB,CAAA;IAC1C,MAAM,EAAE,YAAY,CAAA;IACpB,QAAQ,EAAE,cAAc,CAAA;IACxB,QAAQ,EAAE,eAAe,CAAA;IACzB,SAAS,EAAE,mBAAmB,CAAA;IAC9B,OAAO,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IAC5B,kBAAkB,EAAE,MAAM,eAAe,CAAA;IACzC,QAAQ,EAAE,CAAC,CAAC,SAAS,MAAM,cAAc,EAAE,IAAI,EAAE,CAAC,EAAE,OAAO,EAAE,kBAAkB,CAAC,CAAC,CAAC,KAAK,MAAM,IAAI,CAAA;IACjG,YAAY,CAAC,EAAE,MAAM,MAAM,GAAG,SAAS,CAAA;IACvC,IAAI,CAAC,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAA;IAC1B,SAAS,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAA;CAC/B,CAAA;AAED,6EAA6E;AAC7E,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,UAAU,GAAG,KAAK,CA+DxD"}
|