@go-go-golems/os-scripting 0.1.0 → 0.1.2
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
CHANGED
|
@@ -13,6 +13,28 @@ npm install react react-dom react-redux @reduxjs/toolkit
|
|
|
13
13
|
|
|
14
14
|
`react`, `react-dom`, `react-redux`, and `@reduxjs/toolkit` are peer dependencies.
|
|
15
15
|
|
|
16
|
+
## Bundler note
|
|
17
|
+
|
|
18
|
+
Starting with `@go-go-golems/os-scripting@0.1.1`, package-internal QuickJS bootstrap code is shipped as ordinary generated JavaScript string modules. Consumers do **not** need package-specific Vite dependency-optimization workarounds such as:
|
|
19
|
+
|
|
20
|
+
```ts
|
|
21
|
+
optimizeDeps: {
|
|
22
|
+
exclude: ['@go-go-golems/os-scripting'],
|
|
23
|
+
include: ['debug'],
|
|
24
|
+
}
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
If your own application imports local VM bundle files with Vite raw imports, for example `import code from './bundle.vm.js?raw'`, keep a local declaration such as:
|
|
28
|
+
|
|
29
|
+
```ts
|
|
30
|
+
declare module '*.vm.js?raw' {
|
|
31
|
+
const source: string;
|
|
32
|
+
export default source;
|
|
33
|
+
}
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
That declaration is for your app-authored VM bundles only; it is not required because of package internals.
|
|
37
|
+
|
|
16
38
|
## Main exports
|
|
17
39
|
|
|
18
40
|
```ts
|
|
@@ -65,25 +87,42 @@ export function AppProviders({ children }: { children: React.ReactNode }) {
|
|
|
65
87
|
}
|
|
66
88
|
```
|
|
67
89
|
|
|
68
|
-
Use `createAppStore` when rendering VM surfaces. It includes `runtimeSessions`, runtime lifecycle middleware, and artifact projection middleware. For shell-only apps that never render VM surfaces, `createLauncherStore` from `@go-go-golems/os-shell` is lighter.
|
|
90
|
+
Use `createAppStore` when rendering VM surfaces. It includes `runtimeSessions`, `notifications`, runtime lifecycle middleware, and artifact projection middleware. For shell-only apps that never render VM surfaces, `createLauncherStore` from `@go-go-golems/os-shell` is lighter.
|
|
69
91
|
|
|
70
92
|
## Minimal surface host
|
|
71
93
|
|
|
72
94
|
```tsx
|
|
73
|
-
import {
|
|
95
|
+
import { clearToast, selectToast, Toast } from '@go-go-golems/os-core';
|
|
96
|
+
import { RuntimeSurfaceSessionHost, createAppStore } from '@go-go-golems/os-scripting';
|
|
74
97
|
import type { RuntimeBundleDefinition } from '@go-go-golems/os-shell';
|
|
98
|
+
import { Provider, useDispatch, useSelector } from 'react-redux';
|
|
99
|
+
|
|
100
|
+
const { store } = createAppStore({});
|
|
101
|
+
|
|
102
|
+
function RuntimeToastHost() {
|
|
103
|
+
const dispatch = useDispatch();
|
|
104
|
+
const toast = useSelector((state) => selectToast(state as any));
|
|
105
|
+
|
|
106
|
+
if (!toast) return null;
|
|
107
|
+
return <Toast message={toast} onDone={() => dispatch(clearToast())} />;
|
|
108
|
+
}
|
|
75
109
|
|
|
76
110
|
export function RuntimeWindow({ bundle }: { bundle: RuntimeBundleDefinition }) {
|
|
77
111
|
return (
|
|
78
|
-
<
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
112
|
+
<Provider store={store}>
|
|
113
|
+
<RuntimeSurfaceSessionHost
|
|
114
|
+
windowId="window:demo"
|
|
115
|
+
sessionId="session:demo"
|
|
116
|
+
bundle={bundle}
|
|
117
|
+
/>
|
|
118
|
+
<RuntimeToastHost />
|
|
119
|
+
</Provider>
|
|
83
120
|
);
|
|
84
121
|
}
|
|
85
122
|
```
|
|
86
123
|
|
|
124
|
+
`RuntimeSurfaceSessionHost` routes host effects such as `notify.show` into Redux. Mount host chrome such as `Toast` inside the same `Provider` if your runtime bundles use notification capabilities.
|
|
125
|
+
|
|
87
126
|
## Runtime bundle shape
|
|
88
127
|
|
|
89
128
|
Host TypeScript:
|
|
@@ -100,7 +139,7 @@ export const BUNDLE: RuntimeBundleDefinition = {
|
|
|
100
139
|
plugin: {
|
|
101
140
|
packageIds: ['ui'],
|
|
102
141
|
bundleCode,
|
|
103
|
-
capabilities: { domain: [], system: [] },
|
|
142
|
+
capabilities: { domain: [], system: ['notify.show'] },
|
|
104
143
|
},
|
|
105
144
|
surfaces: {
|
|
106
145
|
home: {
|
|
@@ -128,8 +167,17 @@ defineRuntimeBundle(({ ui }) => ({
|
|
|
128
167
|
return ui.panel([
|
|
129
168
|
ui.text('Hello from QuickJS'),
|
|
130
169
|
ui.text('Session: ' + state.self.sessionId),
|
|
170
|
+
ui.button('Notify host', { onClick: { handler: 'notify' } }),
|
|
131
171
|
]);
|
|
132
172
|
},
|
|
173
|
+
handlers: {
|
|
174
|
+
notify(ctx) {
|
|
175
|
+
ctx.dispatch({
|
|
176
|
+
type: 'notify.show',
|
|
177
|
+
payload: { message: 'Hello from the VM' },
|
|
178
|
+
});
|
|
179
|
+
},
|
|
180
|
+
},
|
|
133
181
|
},
|
|
134
182
|
},
|
|
135
183
|
}));
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { validateRuntimeActions } from './intentSchema';
|
|
2
2
|
import { getRuntimePackageOrThrow, resolveRuntimePackageInstallOrder } from '../runtime-packages';
|
|
3
3
|
import { getRuntimeSurfaceTypeOrThrow } from '../runtime-packs';
|
|
4
|
-
import stackBootstrapSource from './
|
|
4
|
+
import stackBootstrapSource from './stackBootstrapSource.generated';
|
|
5
5
|
import { toJsLiteral } from './quickJsSessionCore';
|
|
6
6
|
import { JsSessionService } from './jsSessionService';
|
|
7
7
|
const DEFAULT_OPTIONS = {
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
declare const source = "const __runtimePackageState =\n globalThis.__runtimePackageState && typeof globalThis.__runtimePackageState === 'object'\n ? globalThis.__runtimePackageState\n : {\n packageIds: [],\n apis: {},\n };\n\nglobalThis.__runtimePackageState = __runtimePackageState;\n\nlet __runtimeBundle = null;\nlet __runtimeActions = [];\n\nfunction isPlainObject(value) {\n return value && typeof value === 'object' && !Array.isArray(value);\n}\n\nfunction mergeRuntimeApiValue(existingValue, incomingValue) {\n if (isPlainObject(existingValue) && isPlainObject(incomingValue)) {\n const merged = { ...existingValue };\n for (const [key, value] of Object.entries(incomingValue)) {\n merged[key] = mergeRuntimeApiValue(merged[key], value);\n }\n return merged;\n }\n\n return incomingValue;\n}\n\nfunction registerRuntimePackageApi(packageId, apiExports) {\n const normalizedPackageId = String(packageId || '').trim();\n if (!normalizedPackageId) {\n throw new Error('registerRuntimePackageApi requires a package id');\n }\n\n if (!__runtimePackageState.packageIds.includes(normalizedPackageId)) {\n __runtimePackageState.packageIds.push(normalizedPackageId);\n }\n\n if (!isPlainObject(apiExports)) {\n return;\n }\n\n for (const [exportName, exportValue] of Object.entries(apiExports)) {\n const mergedValue = mergeRuntimeApiValue(__runtimePackageState.apis[exportName], exportValue);\n __runtimePackageState.apis[exportName] = mergedValue;\n globalThis[exportName] = mergedValue;\n }\n}\n\nfunction collectRuntimePackageApis() {\n return { ...__runtimePackageState.apis };\n}\n\nfunction defineRuntimeBundleImpl(factory) {\n if (typeof factory !== 'function') {\n throw new Error('defineRuntimeBundle requires a factory function');\n }\n\n __runtimeBundle = factory(collectRuntimePackageApis());\n}\n\nfunction assertStackBundleReady() {\n if (!__runtimeBundle || typeof __runtimeBundle !== 'object') {\n throw new Error('Runtime bundle did not register via defineRuntimeBundle');\n }\n}\n\nfunction assertSurfacesMap() {\n assertStackBundleReady();\n if (!__runtimeBundle.surfaces || typeof __runtimeBundle.surfaces !== 'object') {\n __runtimeBundle.surfaces = {};\n }\n return __runtimeBundle.surfaces;\n}\n\nfunction normalizeRuntimeSurfacePackId(surfaceId, packId) {\n const normalizedPackId = typeof packId === 'string' ? packId.trim() : '';\n if (!normalizedPackId) {\n throw new Error('Runtime surface packId is required for surface: ' + String(surfaceId));\n }\n return normalizedPackId;\n}\n\nfunction normalizeRuntimeSurfaceDefinition(surfaceId, definitionOrFactory, packId) {\n const normalizedPackId = normalizeRuntimeSurfacePackId(surfaceId, packId);\n const definition =\n typeof definitionOrFactory === 'function'\n ? definitionOrFactory(collectRuntimePackageApis())\n : definitionOrFactory;\n\n if (!definition || typeof definition !== 'object') {\n throw new Error('Runtime surface definition must be an object for surface: ' + String(surfaceId));\n }\n\n if (typeof definition.render !== 'function') {\n throw new Error('Runtime surface definition render() is required for surface: ' + String(surfaceId));\n }\n\n if (definition.handlers !== undefined) {\n if (!definition.handlers || typeof definition.handlers !== 'object' || Array.isArray(definition.handlers)) {\n throw new Error('Runtime surface definition handlers must be an object for surface: ' + String(surfaceId));\n }\n } else {\n definition.handlers = {};\n }\n\n definition.packId = normalizedPackId;\n return definition;\n}\n\nfunction ensureRuntimeSurfaceRecord(surfaceId) {\n const surfaces = assertSurfacesMap();\n const key = String(surfaceId);\n const existing = surfaces[key];\n if (!existing || typeof existing !== 'object') {\n surfaces[key] = {\n handlers: {},\n };\n } else if (!existing.handlers || typeof existing.handlers !== 'object') {\n existing.handlers = {};\n }\n return surfaces[key];\n}\n\nfunction defineRuntimeSurfaceImpl(surfaceId, definitionOrFactory, packId) {\n const surfaces = assertSurfacesMap();\n const key = String(surfaceId);\n surfaces[key] = normalizeRuntimeSurfaceDefinition(key, definitionOrFactory, packId);\n}\n\nfunction defineRuntimeSurfaceRenderImpl(surfaceId, renderFn) {\n if (typeof renderFn !== 'function') {\n throw new Error('defineRuntimeSurfaceRender requires a render function');\n }\n\n const surface = ensureRuntimeSurfaceRecord(surfaceId);\n surface.render = renderFn;\n}\n\nfunction defineRuntimeSurfaceHandlerImpl(surfaceId, handlerName, handlerFn) {\n if (typeof handlerFn !== 'function') {\n throw new Error('defineRuntimeSurfaceHandler requires a handler function');\n }\n\n const surface = ensureRuntimeSurfaceRecord(surfaceId);\n surface.handlers[String(handlerName)] = handlerFn;\n}\n\nglobalThis.defineRuntimeBundle = defineRuntimeBundleImpl;\nglobalThis.defineRuntimeSurface = defineRuntimeSurfaceImpl;\nglobalThis.defineRuntimeSurfaceRender = defineRuntimeSurfaceRenderImpl;\nglobalThis.defineRuntimeSurfaceHandler = defineRuntimeSurfaceHandlerImpl;\nglobalThis.registerRuntimePackageApi = registerRuntimePackageApi;\n\nglobalThis.__runtimeBundleHost = {\n getMeta() {\n if (!__runtimeBundle || typeof __runtimeBundle !== 'object') {\n throw new Error('Runtime bundle did not register via defineRuntimeBundle');\n }\n\n if (!__runtimeBundle.surfaces || typeof __runtimeBundle.surfaces !== 'object') {\n throw new Error('Runtime bundle surfaces must be an object');\n }\n\n return {\n declaredId: typeof __runtimeBundle.id === 'string' ? __runtimeBundle.id : undefined,\n title: String(__runtimeBundle.title ?? 'Untitled Bundle'),\n description: typeof __runtimeBundle.description === 'string' ? __runtimeBundle.description : undefined,\n packageIds: Array.isArray(__runtimeBundle.packageIds)\n ? __runtimeBundle.packageIds.map((packageId) => String(packageId)).filter((packageId) => packageId.length > 0)\n : [],\n initialSessionState: __runtimeBundle.initialSessionState,\n initialSurfaceState: __runtimeBundle.initialSurfaceState,\n surfaces: Object.keys(__runtimeBundle.surfaces),\n surfaceTypes: Object.fromEntries(\n Object.entries(__runtimeBundle.surfaces).map(([key, surface]) => [\n key,\n normalizeRuntimeSurfacePackId(key, surface?.packId),\n ]),\n ),\n };\n },\n\n renderRuntimeSurface(surfaceId, state) {\n const surface = __runtimeBundle?.surfaces?.[surfaceId];\n if (!surface || typeof surface.render !== 'function') {\n throw new Error('Runtime surface not found or render() is missing: ' + String(surfaceId));\n }\n\n return surface.render({ state });\n },\n\n eventRuntimeSurface(surfaceId, handlerName, args, state) {\n const surface = __runtimeBundle?.surfaces?.[surfaceId];\n if (!surface) {\n throw new Error('Runtime surface not found: ' + String(surfaceId));\n }\n\n const handler = surface.handlers?.[handlerName];\n if (typeof handler !== 'function') {\n throw new Error('Handler not found: ' + String(handlerName));\n }\n\n __runtimeActions = [];\n\n const dispatch = (action) => {\n __runtimeActions.push(action);\n };\n\n handler(\n {\n state,\n dispatch,\n },\n args\n );\n\n return __runtimeActions.slice();\n },\n\n defineRuntimeSurface(surfaceId, definitionOrFactory, packId) {\n defineRuntimeSurfaceImpl(surfaceId, definitionOrFactory, packId);\n return this.getMeta();\n },\n\n defineRuntimeSurfaceRender(surfaceId, renderFn) {\n defineRuntimeSurfaceRenderImpl(surfaceId, renderFn);\n return this.getMeta();\n },\n\n defineRuntimeSurfaceHandler(surfaceId, handlerName, handlerFn) {\n defineRuntimeSurfaceHandlerImpl(surfaceId, handlerName, handlerFn);\n return this.getMeta();\n },\n};\n";
|
|
2
|
+
export default source;
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
// Generated by scripts/packages/generate-vm-source-modules.mjs.
|
|
2
|
+
// Source: stack-bootstrap.vm.js
|
|
3
|
+
// Do not edit by hand.
|
|
4
|
+
const source = "const __runtimePackageState =\n globalThis.__runtimePackageState && typeof globalThis.__runtimePackageState === 'object'\n ? globalThis.__runtimePackageState\n : {\n packageIds: [],\n apis: {},\n };\n\nglobalThis.__runtimePackageState = __runtimePackageState;\n\nlet __runtimeBundle = null;\nlet __runtimeActions = [];\n\nfunction isPlainObject(value) {\n return value && typeof value === 'object' && !Array.isArray(value);\n}\n\nfunction mergeRuntimeApiValue(existingValue, incomingValue) {\n if (isPlainObject(existingValue) && isPlainObject(incomingValue)) {\n const merged = { ...existingValue };\n for (const [key, value] of Object.entries(incomingValue)) {\n merged[key] = mergeRuntimeApiValue(merged[key], value);\n }\n return merged;\n }\n\n return incomingValue;\n}\n\nfunction registerRuntimePackageApi(packageId, apiExports) {\n const normalizedPackageId = String(packageId || '').trim();\n if (!normalizedPackageId) {\n throw new Error('registerRuntimePackageApi requires a package id');\n }\n\n if (!__runtimePackageState.packageIds.includes(normalizedPackageId)) {\n __runtimePackageState.packageIds.push(normalizedPackageId);\n }\n\n if (!isPlainObject(apiExports)) {\n return;\n }\n\n for (const [exportName, exportValue] of Object.entries(apiExports)) {\n const mergedValue = mergeRuntimeApiValue(__runtimePackageState.apis[exportName], exportValue);\n __runtimePackageState.apis[exportName] = mergedValue;\n globalThis[exportName] = mergedValue;\n }\n}\n\nfunction collectRuntimePackageApis() {\n return { ...__runtimePackageState.apis };\n}\n\nfunction defineRuntimeBundleImpl(factory) {\n if (typeof factory !== 'function') {\n throw new Error('defineRuntimeBundle requires a factory function');\n }\n\n __runtimeBundle = factory(collectRuntimePackageApis());\n}\n\nfunction assertStackBundleReady() {\n if (!__runtimeBundle || typeof __runtimeBundle !== 'object') {\n throw new Error('Runtime bundle did not register via defineRuntimeBundle');\n }\n}\n\nfunction assertSurfacesMap() {\n assertStackBundleReady();\n if (!__runtimeBundle.surfaces || typeof __runtimeBundle.surfaces !== 'object') {\n __runtimeBundle.surfaces = {};\n }\n return __runtimeBundle.surfaces;\n}\n\nfunction normalizeRuntimeSurfacePackId(surfaceId, packId) {\n const normalizedPackId = typeof packId === 'string' ? packId.trim() : '';\n if (!normalizedPackId) {\n throw new Error('Runtime surface packId is required for surface: ' + String(surfaceId));\n }\n return normalizedPackId;\n}\n\nfunction normalizeRuntimeSurfaceDefinition(surfaceId, definitionOrFactory, packId) {\n const normalizedPackId = normalizeRuntimeSurfacePackId(surfaceId, packId);\n const definition =\n typeof definitionOrFactory === 'function'\n ? definitionOrFactory(collectRuntimePackageApis())\n : definitionOrFactory;\n\n if (!definition || typeof definition !== 'object') {\n throw new Error('Runtime surface definition must be an object for surface: ' + String(surfaceId));\n }\n\n if (typeof definition.render !== 'function') {\n throw new Error('Runtime surface definition render() is required for surface: ' + String(surfaceId));\n }\n\n if (definition.handlers !== undefined) {\n if (!definition.handlers || typeof definition.handlers !== 'object' || Array.isArray(definition.handlers)) {\n throw new Error('Runtime surface definition handlers must be an object for surface: ' + String(surfaceId));\n }\n } else {\n definition.handlers = {};\n }\n\n definition.packId = normalizedPackId;\n return definition;\n}\n\nfunction ensureRuntimeSurfaceRecord(surfaceId) {\n const surfaces = assertSurfacesMap();\n const key = String(surfaceId);\n const existing = surfaces[key];\n if (!existing || typeof existing !== 'object') {\n surfaces[key] = {\n handlers: {},\n };\n } else if (!existing.handlers || typeof existing.handlers !== 'object') {\n existing.handlers = {};\n }\n return surfaces[key];\n}\n\nfunction defineRuntimeSurfaceImpl(surfaceId, definitionOrFactory, packId) {\n const surfaces = assertSurfacesMap();\n const key = String(surfaceId);\n surfaces[key] = normalizeRuntimeSurfaceDefinition(key, definitionOrFactory, packId);\n}\n\nfunction defineRuntimeSurfaceRenderImpl(surfaceId, renderFn) {\n if (typeof renderFn !== 'function') {\n throw new Error('defineRuntimeSurfaceRender requires a render function');\n }\n\n const surface = ensureRuntimeSurfaceRecord(surfaceId);\n surface.render = renderFn;\n}\n\nfunction defineRuntimeSurfaceHandlerImpl(surfaceId, handlerName, handlerFn) {\n if (typeof handlerFn !== 'function') {\n throw new Error('defineRuntimeSurfaceHandler requires a handler function');\n }\n\n const surface = ensureRuntimeSurfaceRecord(surfaceId);\n surface.handlers[String(handlerName)] = handlerFn;\n}\n\nglobalThis.defineRuntimeBundle = defineRuntimeBundleImpl;\nglobalThis.defineRuntimeSurface = defineRuntimeSurfaceImpl;\nglobalThis.defineRuntimeSurfaceRender = defineRuntimeSurfaceRenderImpl;\nglobalThis.defineRuntimeSurfaceHandler = defineRuntimeSurfaceHandlerImpl;\nglobalThis.registerRuntimePackageApi = registerRuntimePackageApi;\n\nglobalThis.__runtimeBundleHost = {\n getMeta() {\n if (!__runtimeBundle || typeof __runtimeBundle !== 'object') {\n throw new Error('Runtime bundle did not register via defineRuntimeBundle');\n }\n\n if (!__runtimeBundle.surfaces || typeof __runtimeBundle.surfaces !== 'object') {\n throw new Error('Runtime bundle surfaces must be an object');\n }\n\n return {\n declaredId: typeof __runtimeBundle.id === 'string' ? __runtimeBundle.id : undefined,\n title: String(__runtimeBundle.title ?? 'Untitled Bundle'),\n description: typeof __runtimeBundle.description === 'string' ? __runtimeBundle.description : undefined,\n packageIds: Array.isArray(__runtimeBundle.packageIds)\n ? __runtimeBundle.packageIds.map((packageId) => String(packageId)).filter((packageId) => packageId.length > 0)\n : [],\n initialSessionState: __runtimeBundle.initialSessionState,\n initialSurfaceState: __runtimeBundle.initialSurfaceState,\n surfaces: Object.keys(__runtimeBundle.surfaces),\n surfaceTypes: Object.fromEntries(\n Object.entries(__runtimeBundle.surfaces).map(([key, surface]) => [\n key,\n normalizeRuntimeSurfacePackId(key, surface?.packId),\n ]),\n ),\n };\n },\n\n renderRuntimeSurface(surfaceId, state) {\n const surface = __runtimeBundle?.surfaces?.[surfaceId];\n if (!surface || typeof surface.render !== 'function') {\n throw new Error('Runtime surface not found or render() is missing: ' + String(surfaceId));\n }\n\n return surface.render({ state });\n },\n\n eventRuntimeSurface(surfaceId, handlerName, args, state) {\n const surface = __runtimeBundle?.surfaces?.[surfaceId];\n if (!surface) {\n throw new Error('Runtime surface not found: ' + String(surfaceId));\n }\n\n const handler = surface.handlers?.[handlerName];\n if (typeof handler !== 'function') {\n throw new Error('Handler not found: ' + String(handlerName));\n }\n\n __runtimeActions = [];\n\n const dispatch = (action) => {\n __runtimeActions.push(action);\n };\n\n handler(\n {\n state,\n dispatch,\n },\n args\n );\n\n return __runtimeActions.slice();\n },\n\n defineRuntimeSurface(surfaceId, definitionOrFactory, packId) {\n defineRuntimeSurfaceImpl(surfaceId, definitionOrFactory, packId);\n return this.getMeta();\n },\n\n defineRuntimeSurfaceRender(surfaceId, renderFn) {\n defineRuntimeSurfaceRenderImpl(surfaceId, renderFn);\n return this.getMeta();\n },\n\n defineRuntimeSurfaceHandler(surfaceId, handlerName, handlerFn) {\n defineRuntimeSurfaceHandlerImpl(surfaceId, handlerName, handlerFn);\n return this.getMeta();\n },\n};\n";
|
|
5
|
+
export default source;
|