@datalayer/agent-runtimes 1.3.29 → 1.3.32
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/lib/AgentNode.js +14 -33
- package/lib/chat/ChatFloating.js +40 -8
- package/lib/chat/assistant/AssistantStage.d.ts +26 -7
- package/lib/chat/assistant/AssistantStage.js +115 -8
- package/lib/chat/assistant/SpeechBalloon.js +7 -3
- package/lib/chat/assistant/characters.d.ts +32 -1
- package/lib/chat/assistant/characters.js +180 -15
- package/lib/chat/assistant/state.d.ts +28 -0
- package/lib/chat/assistant/state.js +31 -0
- package/lib/chat/base/ChatBase.js +74 -50
- package/lib/chat/base/modelChoice.d.ts +40 -1
- package/lib/chat/base/modelChoice.js +42 -15
- package/lib/chat/prompt/InputPrompt.d.ts +7 -1
- package/lib/chat/prompt/InputPrompt.js +2 -2
- package/lib/chat/prompt/InputPromptBase.js +1 -1
- package/lib/chat/prompt/menus/ModelSelector.d.ts +13 -1
- package/lib/chat/prompt/menus/ModelSelector.js +17 -5
- package/lib/chat/useViewportDrag.d.ts +9 -1
- package/lib/chat/useViewportDrag.js +4 -4
- package/lib/components/a2ui/index.d.ts +2 -0
- package/lib/components/a2ui/index.js +2 -0
- package/lib/components/a2ui/visibility.d.ts +15 -0
- package/lib/components/a2ui/visibility.js +24 -0
- package/lib/components/a2ui/visibleWhen.d.ts +17 -0
- package/lib/components/a2ui/visibleWhen.js +54 -0
- package/lib/examples/ChatAssistantExample.d.ts +4 -0
- package/lib/examples/ChatAssistantExample.js +26 -5
- package/lib/examples/utils/owlCharacterPlugin.d.ts +7 -0
- package/lib/examples/utils/owlCharacterPlugin.js +44 -0
- package/lib/loop/apps/AppFeedback.d.ts +27 -0
- package/lib/loop/apps/AppFeedback.js +78 -0
- package/lib/loop/apps/AppRenderer.d.ts +33 -1
- package/lib/loop/apps/AppRenderer.js +111 -29
- package/lib/loop/apps/agent.d.ts +15 -0
- package/lib/loop/apps/agent.js +42 -0
- package/lib/loop/apps/appspec.js +6 -3
- package/lib/loop/apps/checks.d.ts +10 -2
- package/lib/loop/apps/checks.js +21 -10
- package/lib/loop/apps/feedback.d.ts +51 -0
- package/lib/loop/apps/feedback.js +61 -0
- package/lib/loop/apps/index.d.ts +3 -0
- package/lib/loop/apps/index.js +3 -0
- package/lib/loop/apps/rules.d.ts +14 -0
- package/lib/loop/apps/rules.js +24 -0
- package/lib/loop/core/canvasBlocks.d.ts +16 -0
- package/lib/loop/core/canvasBlocks.js +13 -0
- package/lib/loop/core/index.d.ts +15 -0
- package/lib/loop/core/index.js +3 -0
- package/lib/loop/embed/AppEmbed.d.ts +42 -0
- package/lib/loop/embed/AppEmbed.js +205 -0
- package/lib/loop/embed/datalayer-app.d.ts +1 -0
- package/lib/loop/embed/datalayer-app.js +16 -0
- package/lib/loop/embed/element.d.ts +57 -0
- package/lib/loop/embed/element.js +405 -0
- package/lib/loop/embed/embedConfig.d.ts +120 -0
- package/lib/loop/embed/embedConfig.js +148 -0
- package/lib/loop/embed/embedTheme.d.ts +24 -0
- package/lib/loop/embed/embedTheme.js +83 -0
- package/lib/loop/index.d.ts +6 -2
- package/lib/loop/index.js +8 -2
- package/lib/loop/plugins/a2ui/A2uiView.js +2 -3
- package/lib/loop/plugins/a2ui-surface/InlineSurface.d.ts +23 -3
- package/lib/loop/plugins/a2ui-surface/InlineSurface.js +36 -9
- package/lib/loop/plugins/agent-capacity/index.d.ts +4 -0
- package/lib/loop/plugins/agent-capacity/index.js +3 -1
- package/lib/loop/plugins/agents/switchable.d.ts +7 -0
- package/lib/loop/plugins/agents/switchable.js +91 -88
- package/lib/loop/plugins/app-page/AppPage.d.ts +16 -0
- package/lib/loop/plugins/app-page/AppPage.js +53 -0
- package/lib/loop/plugins/app-page/appPageModel.d.ts +180 -0
- package/lib/loop/plugins/app-page/appPageModel.js +443 -0
- package/lib/loop/plugins/app-page/index.d.ts +8 -0
- package/lib/loop/plugins/app-page/index.js +34 -0
- package/lib/loop/plugins/canvas-blocks/index.d.ts +63 -0
- package/lib/loop/plugins/canvas-blocks/index.js +118 -0
- package/lib/loop/plugins/chat/ChatView.js +52 -26
- package/lib/loop/plugins/chat/turnState.d.ts +5 -2
- package/lib/loop/plugins/chat/turnState.js +2 -1
- package/lib/loop/plugins/page-layout/SplitLayout.d.ts +31 -0
- package/lib/loop/plugins/page-layout/SplitLayout.js +129 -0
- package/lib/loop/plugins/page-layout/index.d.ts +13 -0
- package/lib/loop/plugins/page-layout/index.js +10 -1
- package/lib/loop/presets.d.ts +12 -0
- package/lib/loop/presets.js +5 -3
- package/lib/specs/actions.js +9 -0
- package/lib/specs/agents/agents.js +20 -4
- package/lib/specs/apps.d.ts +10 -1
- package/lib/specs/apps.js +1779 -154
- package/lib/specs/appspecSchema.js +14 -8
- package/lib/specs/models.d.ts +1 -1
- package/lib/specs/models.js +8 -8
- package/lib/specs/tools.d.ts +1 -0
- package/lib/specs/tools.js +19 -0
- package/lib/stories/loop/LoopReference.stories.d.ts +21 -0
- package/lib/stories/loop/LoopReference.stories.js +31 -0
- package/lib/stories/loop/ReferenceScreens.d.ts +53 -0
- package/lib/stories/loop/ReferenceScreens.js +256 -0
- package/lib/stories/loop/pictures-main.d.ts +1 -0
- package/lib/stories/loop/pictures-main.js +64 -0
- package/lib/types/agentspecs.d.ts +17 -1
- package/lib/types/chat.d.ts +5 -0
- package/lib/types/config.d.ts +20 -0
- package/package.json +10 -6
- package/scripts/check-cloudflare-models.py +2 -2
- package/scripts/codegen/generate_agents.py +50 -2
- package/scripts/codegen/generate_apps.py +38 -7
- package/scripts/codegen/generate_models.py +4 -4
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import type { CSSProperties, JSX, ReactNode } from 'react';
|
|
2
|
+
import type { AppAccent, AppEmbedMode, AppSpec } from '../../types/agentspecs';
|
|
3
|
+
import { type AppInstance } from '../apps/AppRenderer';
|
|
4
|
+
import { type EmbedColorMode } from './embedConfig';
|
|
5
|
+
export type AppEmbedProps = {
|
|
6
|
+
/** The application. */
|
|
7
|
+
app: AppSpec;
|
|
8
|
+
/** How it sits in the page; the Appspec's `deployment.embedded.mode` by default. */
|
|
9
|
+
mode?: AppEmbedMode;
|
|
10
|
+
/** The host's accent; the application's own by default. */
|
|
11
|
+
accent?: AppAccent;
|
|
12
|
+
/** Light, dark, or the visitor's system. */
|
|
13
|
+
colorMode?: EmbedColorMode;
|
|
14
|
+
/** The host's face, a CSS font family; the theme's by default. */
|
|
15
|
+
font?: string;
|
|
16
|
+
/**
|
|
17
|
+
* An agent-runtimes server the application's agent runs on. Without one,
|
|
18
|
+
* it runs on a Datalayer runtime, launched with the visitor's Datalayer
|
|
19
|
+
* credentials.
|
|
20
|
+
*/
|
|
21
|
+
serverUrl?: string;
|
|
22
|
+
/** What its record is kept under, on Datalayer. */
|
|
23
|
+
instance?: AppInstance;
|
|
24
|
+
/** Height of an inline application. */
|
|
25
|
+
height?: number | string;
|
|
26
|
+
/**
|
|
27
|
+
* Draw overlays — menus, dialogs — inside the embed's own root rather than
|
|
28
|
+
* in Primer's, in the host's `<body>`: what the element asks for, since a
|
|
29
|
+
* shadow root's styles stop at its edge. A React host leaves it off.
|
|
30
|
+
*/
|
|
31
|
+
ownPortal?: boolean;
|
|
32
|
+
};
|
|
33
|
+
/** The `loop` theme, with the application's (or the host's) accent and face. */
|
|
34
|
+
export declare function EmbedThemed({ accent, colorMode, font, children, style, }: {
|
|
35
|
+
accent: AppAccent;
|
|
36
|
+
colorMode: 'light' | 'dark';
|
|
37
|
+
font?: string;
|
|
38
|
+
children: ReactNode;
|
|
39
|
+
style?: CSSProperties;
|
|
40
|
+
}): JSX.Element;
|
|
41
|
+
export declare function AppEmbed({ app, mode, accent, colorMode, font, serverUrl, instance, height, ownPortal, }: AppEmbedProps): JSX.Element;
|
|
42
|
+
export default AppEmbed;
|
|
@@ -0,0 +1,205 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
/*
|
|
3
|
+
* Copyright (c) 2025-2026 Datalayer, Inc.
|
|
4
|
+
* Distributed under the terms of the Modified BSD License.
|
|
5
|
+
*/
|
|
6
|
+
/**
|
|
7
|
+
* An application in another product's page, as a React component (LOOP
|
|
8
|
+
* D-07, D-09, D-11): what the `<datalayer-app>` element draws, and what a
|
|
9
|
+
* host that uses React mounts itself.
|
|
10
|
+
*
|
|
11
|
+
* Four modes, as the Appspec says (`deployment.embedded.mode`) or the host:
|
|
12
|
+
*
|
|
13
|
+
* - **inline** — the application where the component is: `AppRenderer`, its
|
|
14
|
+
* page beside its conversation when it has one;
|
|
15
|
+
* - **bubble** — a round button in the corner that opens the conversation in
|
|
16
|
+
* a popup, the copilot pattern;
|
|
17
|
+
* - **panel** — the conversation at the right edge of the page, at full
|
|
18
|
+
* height;
|
|
19
|
+
* - **assistant** — the application's character on the page, speaking in a
|
|
20
|
+
* balloon (§6.9), the one its Appspec names (`interface.assistant`).
|
|
21
|
+
*
|
|
22
|
+
* The three floating modes are `ChatFloating`'s, given the application's
|
|
23
|
+
* name, welcome, starters and accent, and its agent's endpoint — created
|
|
24
|
+
* with the application's spec in its payload, so the runtime enforces its
|
|
25
|
+
* rules there as it does inline.
|
|
26
|
+
*
|
|
27
|
+
* In the `loop` theme with the application's accent (T-12, T-05), which the
|
|
28
|
+
* host may override with the face and the mode (D-11).
|
|
29
|
+
*
|
|
30
|
+
* @module loop/embed/AppEmbed
|
|
31
|
+
*/
|
|
32
|
+
import { useEffect, useLayoutEffect, useMemo, useRef, useState } from 'react';
|
|
33
|
+
import { registerPortalRoot } from '@primer/react';
|
|
34
|
+
import { DatalayerThemeProvider, loopTheme } from '@datalayer/primer-addons';
|
|
35
|
+
import { useIAMStore } from '@datalayer/core/lib/state/substates/IAMState';
|
|
36
|
+
import { ChatFloating } from '../../chat/ChatFloating';
|
|
37
|
+
import { useAgentRuntimes } from '../../hooks/useAgentRuntimes';
|
|
38
|
+
import { AppRenderer, DATALAYER_BOOTSTRAP_AGENTSPEC, appDatalayerCreatePayload, defineAppPlugin, } from '../apps/AppRenderer';
|
|
39
|
+
import { LoopAgentBlueprint } from '../core';
|
|
40
|
+
import { ensureServerAgent } from '../plugins/agents/switchable';
|
|
41
|
+
import { floatingViewOf } from './embedConfig';
|
|
42
|
+
import { embedThemeStyles } from './embedTheme';
|
|
43
|
+
/** What the application's agent is created with on an agent-runtimes server. */
|
|
44
|
+
function serverCreatePayload(app) {
|
|
45
|
+
const blueprint = (defineAppPlugin(app).contributes ?? []).find((item) => item.point === LoopAgentBlueprint);
|
|
46
|
+
return blueprint?.value.createPayload ?? { name: app.id };
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* The application's agent on the host's agent-runtimes server: created
|
|
50
|
+
* there with the application's spec unless it is there already, as the
|
|
51
|
+
* workspace's Local target does.
|
|
52
|
+
*/
|
|
53
|
+
function useServerAgent(app, serverUrl) {
|
|
54
|
+
const [state, setState] = useState({
|
|
55
|
+
waiting: 'Starting…',
|
|
56
|
+
});
|
|
57
|
+
const source = JSON.stringify(app);
|
|
58
|
+
useEffect(() => {
|
|
59
|
+
let cancelled = false;
|
|
60
|
+
const base = serverUrl.replace(/\/+$/, '');
|
|
61
|
+
setState({ waiting: 'Starting…' });
|
|
62
|
+
ensureServerAgent(base, app.id, serverCreatePayload(app)).then(() => {
|
|
63
|
+
if (!cancelled) {
|
|
64
|
+
setState({
|
|
65
|
+
protocol: {
|
|
66
|
+
type: 'ag-ui',
|
|
67
|
+
endpoint: `${base}/api/v1/ag-ui/${app.id}/`,
|
|
68
|
+
agentId: app.id,
|
|
69
|
+
},
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
}, (error) => {
|
|
73
|
+
if (!cancelled) {
|
|
74
|
+
setState({
|
|
75
|
+
error: error instanceof Error ? error.message : String(error),
|
|
76
|
+
});
|
|
77
|
+
}
|
|
78
|
+
});
|
|
79
|
+
return () => {
|
|
80
|
+
cancelled = true;
|
|
81
|
+
};
|
|
82
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
83
|
+
}, [serverUrl, source]);
|
|
84
|
+
return state;
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* The application's agent on a Datalayer runtime: allocated with a plain
|
|
88
|
+
* agentspec, the agent created there with the application's spec — the
|
|
89
|
+
* runtime `AppRenderer` launches inline (R-03, R-05).
|
|
90
|
+
*/
|
|
91
|
+
function useDatalayerAgent(app, instance) {
|
|
92
|
+
const token = useIAMStore(state => state.token);
|
|
93
|
+
const source = JSON.stringify(app);
|
|
94
|
+
const agentConfig = useMemo(() => ({
|
|
95
|
+
name: app.id,
|
|
96
|
+
protocol: 'ag-ui',
|
|
97
|
+
agentSpecId: DATALAYER_BOOTSTRAP_AGENTSPEC,
|
|
98
|
+
createPayload: appDatalayerCreatePayload(app, instance),
|
|
99
|
+
}),
|
|
100
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
101
|
+
[source, instance?.appUid, instance?.deploymentUid, instance?.version]);
|
|
102
|
+
const { runtime, error } = useAgentRuntimes({
|
|
103
|
+
agentSpecId: DATALAYER_BOOTSTRAP_AGENTSPEC,
|
|
104
|
+
agentConfig,
|
|
105
|
+
variant: 'cloud-pydanticai',
|
|
106
|
+
// Only for a visitor Datalayer knows: a runtime is somebody's to pay for.
|
|
107
|
+
autoStart: Boolean(token),
|
|
108
|
+
autoCreateAgent: Boolean(token),
|
|
109
|
+
});
|
|
110
|
+
if (!token) {
|
|
111
|
+
return {
|
|
112
|
+
error: `${app.name} runs on Datalayer, which needs you signed in. An application embedded for visitors who are not needs its embed token (LOOP D-14), or an agent-runtimes server of the host's own (the "server" attribute).`,
|
|
113
|
+
};
|
|
114
|
+
}
|
|
115
|
+
if (error) {
|
|
116
|
+
return { error };
|
|
117
|
+
}
|
|
118
|
+
if (!runtime?.agentBaseUrl) {
|
|
119
|
+
return { waiting: 'Starting…' };
|
|
120
|
+
}
|
|
121
|
+
return {
|
|
122
|
+
protocol: {
|
|
123
|
+
type: 'ag-ui',
|
|
124
|
+
endpoint: `${runtime.agentBaseUrl}/api/v1/ag-ui/${app.id}/`,
|
|
125
|
+
agentId: app.id,
|
|
126
|
+
authToken: token,
|
|
127
|
+
},
|
|
128
|
+
};
|
|
129
|
+
}
|
|
130
|
+
/** The application's face, as the floating chat's button and header draw it. */
|
|
131
|
+
function Face({ emoji }) {
|
|
132
|
+
return (_jsx("span", { "aria-hidden": true, style: { fontSize: 18, lineHeight: 1 }, children: emoji }));
|
|
133
|
+
}
|
|
134
|
+
/** The bubble, the panel and the assistant: `ChatFloating` in that mode. */
|
|
135
|
+
function FloatingChat({ app, view, colorMode, agent, }) {
|
|
136
|
+
const welcome = app.interface.welcome || app.description;
|
|
137
|
+
return (_jsx(ChatFloating
|
|
138
|
+
// A new agent is a new conversation.
|
|
139
|
+
, { defaultViewMode: view, assistantCharacter: app.interface.assistant ?? 'paperclip', protocol: agent.protocol, authToken: agent.protocol?.authToken, title: app.name, description: welcome, brandIcon: _jsx(Face, { emoji: app.emoji }), buttonIcon: _jsx(Face, { emoji: app.emoji }), buttonTooltip: `Talk to ${app.name}`, suggestions: app.interface.starters.map(starter => ({
|
|
140
|
+
title: starter.label,
|
|
141
|
+
message: starter.message,
|
|
142
|
+
})), themeVariant: "loop", colorMode: colorMode, showTokenUsage: false, showSettingsButton: false, showPoweredBy: false, useStore: false, launching: !agent.protocol && !agent.error, launchingMessage: agent.waiting, disabled: Boolean(agent.error), disableReason: agent.error }, agent.protocol?.endpoint ?? 'waiting'));
|
|
143
|
+
}
|
|
144
|
+
/** Floating, its agent on the host's agent-runtimes server. */
|
|
145
|
+
function ServerFloating({ serverUrl, ...props }) {
|
|
146
|
+
return (_jsx(FloatingChat, { ...props, agent: useServerAgent(props.app, serverUrl) }));
|
|
147
|
+
}
|
|
148
|
+
/** Floating, its agent on a Datalayer runtime. */
|
|
149
|
+
function DatalayerFloating({ instance, ...props }) {
|
|
150
|
+
return (_jsx(FloatingChat, { ...props, agent: useDatalayerAgent(props.app, instance) }));
|
|
151
|
+
}
|
|
152
|
+
/**
|
|
153
|
+
* Overlays — menus, dialogs — drawn inside the embed's own root, under the
|
|
154
|
+
* theme's element, so that they wear its theme: what the element asks for,
|
|
155
|
+
* since Primer's own portal root is in the host's `<body>`, outside the
|
|
156
|
+
* shadow root and its styles.
|
|
157
|
+
*/
|
|
158
|
+
function OwnPortalRoot() {
|
|
159
|
+
const ref = useRef(null);
|
|
160
|
+
useLayoutEffect(() => {
|
|
161
|
+
if (ref.current) {
|
|
162
|
+
registerPortalRoot(ref.current);
|
|
163
|
+
}
|
|
164
|
+
}, []);
|
|
165
|
+
return _jsx("div", { ref: ref, className: "datalayer-app-portal" });
|
|
166
|
+
}
|
|
167
|
+
/** The visitor's system mode, followed while it changes. */
|
|
168
|
+
function useSystemMode() {
|
|
169
|
+
const query = typeof window !== 'undefined' && typeof window.matchMedia === 'function'
|
|
170
|
+
? window.matchMedia('(prefers-color-scheme: dark)')
|
|
171
|
+
: null;
|
|
172
|
+
const [dark, setDark] = useState(Boolean(query?.matches));
|
|
173
|
+
useEffect(() => {
|
|
174
|
+
if (!query) {
|
|
175
|
+
return undefined;
|
|
176
|
+
}
|
|
177
|
+
const follow = () => setDark(query.matches);
|
|
178
|
+
query.addEventListener?.('change', follow);
|
|
179
|
+
return () => query.removeEventListener?.('change', follow);
|
|
180
|
+
}, [query]);
|
|
181
|
+
return dark ? 'dark' : 'light';
|
|
182
|
+
}
|
|
183
|
+
/** The `loop` theme, with the application's (or the host's) accent and face. */
|
|
184
|
+
export function EmbedThemed({ accent, colorMode, font, children, style, }) {
|
|
185
|
+
const themeStyles = useMemo(() => embedThemeStyles({ accent, font }), [accent, font]);
|
|
186
|
+
return (
|
|
187
|
+
/*
|
|
188
|
+
* Marked as themed above the provider, so that the provider counts
|
|
189
|
+
* itself nested and leaves the host's <body> and Primer's portal root
|
|
190
|
+
* alone: it would otherwise write the theme's tokens, colour and face on
|
|
191
|
+
* the host's page (T-13). A wrapper of no box.
|
|
192
|
+
*/
|
|
193
|
+
_jsx("div", { "data-color-mode": colorMode, style: { display: 'contents' }, children: _jsx(DatalayerThemeProvider, { colorMode: colorMode, theme: loopTheme, themeStyles: themeStyles, baseStyles: style, children: children }) }));
|
|
194
|
+
}
|
|
195
|
+
export function AppEmbed({ app, mode, accent, colorMode = 'auto', font, serverUrl, instance, height = 640, ownPortal = false, }) {
|
|
196
|
+
const system = useSystemMode();
|
|
197
|
+
const resolvedMode = colorMode === 'auto' ? system : colorMode;
|
|
198
|
+
const shownAs = mode ?? app.deployment.embedded?.mode ?? 'inline';
|
|
199
|
+
const view = floatingViewOf(shownAs);
|
|
200
|
+
return (_jsxs(EmbedThemed, { accent: accent ?? app.interface.accent, colorMode: resolvedMode, font: font, style: view
|
|
201
|
+
? // Floating: nothing in the page's flow, nothing painted behind.
|
|
202
|
+
{ backgroundColor: 'transparent' }
|
|
203
|
+
: { height, display: 'flex', flexDirection: 'column' }, children: [ownPortal ? _jsx(OwnPortalRoot, {}) : null, view && serverUrl ? (_jsx(ServerFloating, { app: app, view: view, serverUrl: serverUrl, colorMode: resolvedMode })) : view ? (_jsx(DatalayerFloating, { app: app, view: view, instance: instance, colorMode: resolvedMode })) : (_jsx(AppRenderer, { app: app, target: serverUrl ? 'local' : 'datalayer', ...(serverUrl ? { serverUrl } : {}), instance: instance }))] }));
|
|
204
|
+
}
|
|
205
|
+
export default AppEmbed;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright (c) 2025-2026 Datalayer, Inc.
|
|
3
|
+
* Distributed under the terms of the Modified BSD License.
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* The one script a host loads (LOOP D-08): it defines `<datalayer-app>` and
|
|
7
|
+
* nothing else. Built on its own by `npm run build:embed`
|
|
8
|
+
* (`vite.embed.config.ts`) into `dist-embed/datalayer-app.js`, with the
|
|
9
|
+
* stylesheet the element links into its shadow root beside it
|
|
10
|
+
* (`dist-embed/datalayer-app.css`); served from a Datalayer origin at
|
|
11
|
+
* `/embed/`.
|
|
12
|
+
*
|
|
13
|
+
* @module loop/embed/datalayer-app
|
|
14
|
+
*/
|
|
15
|
+
import { defineDatalayerAppElement } from './element';
|
|
16
|
+
defineDatalayerAppElement();
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import type { AppSpec } from '../../types/agentspecs';
|
|
2
|
+
import { type ParsedAppspec } from '../apps/appspec';
|
|
3
|
+
/** What the framed run page and the element say to each other. */
|
|
4
|
+
export declare const EMBED_MESSAGES: {
|
|
5
|
+
readonly size: "datalayer-app:size";
|
|
6
|
+
readonly decision: "datalayer-app:decision";
|
|
7
|
+
/** To the frame: an embed token, the first or a new one. */
|
|
8
|
+
readonly token: "datalayer-app:token";
|
|
9
|
+
/** From the frame: the token lapsed; a new one is needed. */
|
|
10
|
+
readonly tokenExpired: "datalayer-app:token-expired";
|
|
11
|
+
};
|
|
12
|
+
/** Where an application comes from, once read. */
|
|
13
|
+
export type EmbedSource = {
|
|
14
|
+
kind: 'spec';
|
|
15
|
+
app: AppSpec;
|
|
16
|
+
} | {
|
|
17
|
+
kind: 'frame';
|
|
18
|
+
src: string;
|
|
19
|
+
} | {
|
|
20
|
+
kind: 'said';
|
|
21
|
+
text: string;
|
|
22
|
+
expired?: boolean;
|
|
23
|
+
};
|
|
24
|
+
/** An Appspec from its text, YAML or JSON; refused in a sentence when it is neither. */
|
|
25
|
+
export declare function appspecOfText(text: string): AppSpec;
|
|
26
|
+
/**
|
|
27
|
+
* An application the embed can run, or a sentence saying why not: one with
|
|
28
|
+
* an id, and an agent to answer — what the spec tolerates in a draft, an
|
|
29
|
+
* embed cannot run.
|
|
30
|
+
*/
|
|
31
|
+
export declare function runnable({ app, problems }: ParsedAppspec): AppSpec;
|
|
32
|
+
/** The run page an application on Datalayer is framed from. */
|
|
33
|
+
export declare function frameSrcOf(origin: string, app: string, token?: string): string;
|
|
34
|
+
/**
|
|
35
|
+
* An application on Datalayer, read with its embed token: what the space
|
|
36
|
+
* keeps of it (`model_s`, the stored definition), whose `spec` is the
|
|
37
|
+
* Appspec. A decision is framed; so is an application that has no spec.
|
|
38
|
+
*/
|
|
39
|
+
export declare function readEmbeddedApp({ api, origin, app, token, fetcher, }: {
|
|
40
|
+
api: string;
|
|
41
|
+
origin: string;
|
|
42
|
+
app: string;
|
|
43
|
+
token: string;
|
|
44
|
+
fetcher?: typeof fetch;
|
|
45
|
+
}): Promise<EmbedSource>;
|
|
46
|
+
export type DatalayerAppElementOptions = {
|
|
47
|
+
/** The element's name; `datalayer-app` by default. */
|
|
48
|
+
tag?: string;
|
|
49
|
+
/** Where the script was loaded from: the default origin, and where its stylesheet is. */
|
|
50
|
+
scriptUrl?: string;
|
|
51
|
+
};
|
|
52
|
+
/**
|
|
53
|
+
* Define the element, once. Returns its class, or `undefined` where there is
|
|
54
|
+
* no `customElements` (a server render) — a second call returns the class
|
|
55
|
+
* already defined.
|
|
56
|
+
*/
|
|
57
|
+
export declare function defineDatalayerAppElement(options?: DatalayerAppElementOptions): CustomElementConstructor | undefined;
|