@zaflun/lumio-sdk 0.6.3 → 0.10.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/README.md +5 -4
- package/dist/chunk-GVAYWB5X.js +196 -0
- package/dist/host.d.ts +72 -0
- package/dist/host.js +340 -0
- package/dist/index.d.ts +41 -12
- package/dist/index.js +129 -198
- package/dist/lumio-runtime.global.js +1072 -160
- package/dist/server.d.ts +147 -77
- package/dist/server.js +11 -5
- package/package.json +16 -12
package/dist/index.d.ts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import React, { CSSProperties } from 'react';
|
|
2
|
-
import { LumioEventType, LumioActionType, Sound } from '@zaflun/lumio-protocol';
|
|
2
|
+
import { LumioEventType, LumioEventPayloadMap, LumioActionType, Sound } from '@zaflun/lumio-protocol';
|
|
3
3
|
export { Sound } from '@zaflun/lumio-protocol';
|
|
4
4
|
|
|
5
5
|
interface RenderOptions {
|
|
6
|
-
target: "editor" | "layer"
|
|
6
|
+
target: "editor" | "layer";
|
|
7
7
|
}
|
|
8
8
|
declare const Lumio: {
|
|
9
9
|
render(element: React.ReactElement, options: RenderOptions): void;
|
|
@@ -338,19 +338,37 @@ declare function useVisionState<T>(key: string, defaultValue: T): [T, (value: T)
|
|
|
338
338
|
|
|
339
339
|
interface ExtensionContext {
|
|
340
340
|
extensionId: string | null;
|
|
341
|
-
target: "editor" | "layer" |
|
|
341
|
+
target: "editor" | "layer" | null;
|
|
342
342
|
overlayId: string | null;
|
|
343
|
-
interactiveUrl: string | null;
|
|
344
343
|
}
|
|
344
|
+
/**
|
|
345
|
+
* The install this surface renders. Set from `lifecycle.init`, which the host
|
|
346
|
+
* sends before the bundle runs, so the first render already has it.
|
|
347
|
+
*/
|
|
345
348
|
declare function useExtensionContext(): ExtensionContext;
|
|
346
349
|
|
|
347
|
-
|
|
350
|
+
/**
|
|
351
|
+
* The latest payload of one platform event type, or `null` until the first
|
|
352
|
+
* one arrives. The payload type follows `type`, e.g.
|
|
353
|
+
* `useLumioEvent("twitch:cheer")?.bits` is a `number`.
|
|
354
|
+
*/
|
|
355
|
+
declare function useLumioEvent<K extends LumioEventType>(eventType: K): LumioEventPayloadMap[K] | null;
|
|
356
|
+
|
|
357
|
+
/**
|
|
358
|
+
* Calls `cb` with the payload of every message a handler of this install
|
|
359
|
+
* pushes on `topic` with `ctx.realtime.push(topic, payload)`. Runs on every
|
|
360
|
+
* rendered surface of the install (editor and layer). The host delivers what
|
|
361
|
+
* arrives while the surface is open; nothing is replayed.
|
|
362
|
+
*
|
|
363
|
+
* `cb` may change between renders without re-subscribing.
|
|
364
|
+
*/
|
|
365
|
+
declare function useRealtime<T = unknown>(topic: string, cb: (payload: T) => void): void;
|
|
348
366
|
|
|
349
367
|
interface LumioConfig {
|
|
350
368
|
extension_id?: string;
|
|
351
369
|
install_id?: string;
|
|
352
370
|
account_id?: string;
|
|
353
|
-
target?: "editor" | "layer"
|
|
371
|
+
target?: "editor" | "layer";
|
|
354
372
|
permissions?: string[];
|
|
355
373
|
settings?: Record<string, unknown>;
|
|
356
374
|
}
|
|
@@ -361,6 +379,11 @@ declare global {
|
|
|
361
379
|
__lumio_on_config?: (fn: (config: LumioConfig) => void) => () => void;
|
|
362
380
|
}
|
|
363
381
|
}
|
|
382
|
+
/**
|
|
383
|
+
* The install's config. Starts from `lifecycle.init`, which the host sends
|
|
384
|
+
* before the bundle runs, so the first render already has it. A
|
|
385
|
+
* `config.update` from the host replaces only the fields it carries.
|
|
386
|
+
*/
|
|
364
387
|
declare function useLumioConfig(): [LumioConfig, (configOrUpdater: LumioConfig | ((prev: LumioConfig) => LumioConfig)) => void];
|
|
365
388
|
|
|
366
389
|
interface OverlayTheme {
|
|
@@ -389,11 +412,12 @@ interface OverlayTheme {
|
|
|
389
412
|
* Returns the active overlay/widget theme variables.
|
|
390
413
|
*
|
|
391
414
|
* Extensions use this to style themselves consistently with the
|
|
392
|
-
* overlay or widget they're rendered in. Only relevant for `layer`
|
|
393
|
-
*
|
|
415
|
+
* overlay or widget they're rendered in. Only relevant for the `layer`
|
|
416
|
+
* target (stream overlay, widget pages).
|
|
394
417
|
*
|
|
395
|
-
*
|
|
396
|
-
*
|
|
418
|
+
* The theme comes from `lifecycle.init`, which the host sends before the
|
|
419
|
+
* bundle runs, so the first render already has it. A `theme.change` from the
|
|
420
|
+
* host updates it.
|
|
397
421
|
*/
|
|
398
422
|
declare function useLumioTheme(): OverlayTheme;
|
|
399
423
|
|
|
@@ -402,10 +426,15 @@ interface LumioIdentity {
|
|
|
402
426
|
accountId: string | null;
|
|
403
427
|
role: string | null;
|
|
404
428
|
}
|
|
429
|
+
/**
|
|
430
|
+
* Who this surface renders for. Set from `lifecycle.init`, which the host
|
|
431
|
+
* sends before the bundle runs, so the first render already has it.
|
|
432
|
+
*/
|
|
405
433
|
declare function useLumioIdentity(): LumioIdentity;
|
|
406
434
|
|
|
407
435
|
interface UseLumioActionResult {
|
|
408
|
-
|
|
436
|
+
/** Runs the action. Resolves once it settled; a failure lands in `error`, never as a rejection. */
|
|
437
|
+
execute: (params?: Record<string, unknown>) => Promise<void>;
|
|
409
438
|
data: unknown | null;
|
|
410
439
|
isLoading: boolean;
|
|
411
440
|
error: string | null;
|
|
@@ -690,4 +719,4 @@ interface LocalFontDefinition {
|
|
|
690
719
|
}
|
|
691
720
|
declare function localFont(options: LocalFontOptions): LocalFontDefinition;
|
|
692
721
|
|
|
693
|
-
export { ANIMATION_PRESETS, Animated, type AnimatedProps, type AnimationPresetName, Box, type BoxProps, Button, type ButtonProps, CompactView, type CompactViewProps, Dropdown, type DropdownOption, type DropdownProps, EditorButton, type EditorButtonProps, EditorChannelRow, type EditorChannelRowProps, EditorCheckbox, type EditorCheckboxProps, EditorColorPicker, type EditorColorPickerProps, EditorDivider, EditorFontPicker, type EditorFontPickerProps, EditorFontRow, type EditorFontRowProps, EditorGroup, type EditorGroupProps, EditorInfo, type EditorInfoProps, EditorInput, type EditorInputProps, EditorLabel, type EditorLabelProps, EditorSelect, type EditorSelectOption, type EditorSelectProps, EditorSlider, type EditorSliderProps, EditorTextarea, type EditorTextareaProps, type ExtensionContext, type FontDisplay, type FontSource, HStack, type HStackProps, IconDisplay, type IconDisplayProps, IconPicker, type IconPickerProps, type IconPickerSize, type IconSource, type IconValue, Image, type ImageProps, type KeyframeBlock, type KeyframeDefinition, List, type ListProps, type LocalFontDefinition, type LocalFontOptions, Lumio, type LumioConfig, type LumioIdentity, NumberField, type NumberFieldProps, type OverlayTheme, type RenderOptions, Slider, type SliderProps, Text, TextArea, type TextAreaProps, TextField, type TextFieldProps, type TextProps, Toggle, type ToggleProps, type UseAnimationResult, type UseIconPickerOptions, type UseIconPickerResult, type UseLumioActionResult, type UseLumioSoundResult, type UseMutationResult, type UseQueryResult, VStack, type VStackProps, type VisionStyle, WorkerBridge, defineKeyframes, flushKeyframes, getPreset, localFont, useAnimation, useEditorAction, useExtensionContext, useExtensionStorage, useIconPicker, useLumioAction, useLumioConfig, useLumioEvent, useLumioIdentity, useLumioSound, useLumioTheme, useMutation, useQuery, useVisionState };
|
|
722
|
+
export { ANIMATION_PRESETS, Animated, type AnimatedProps, type AnimationPresetName, Box, type BoxProps, Button, type ButtonProps, CompactView, type CompactViewProps, Dropdown, type DropdownOption, type DropdownProps, EditorButton, type EditorButtonProps, EditorChannelRow, type EditorChannelRowProps, EditorCheckbox, type EditorCheckboxProps, EditorColorPicker, type EditorColorPickerProps, EditorDivider, EditorFontPicker, type EditorFontPickerProps, EditorFontRow, type EditorFontRowProps, EditorGroup, type EditorGroupProps, EditorInfo, type EditorInfoProps, EditorInput, type EditorInputProps, EditorLabel, type EditorLabelProps, EditorSelect, type EditorSelectOption, type EditorSelectProps, EditorSlider, type EditorSliderProps, EditorTextarea, type EditorTextareaProps, type ExtensionContext, type FontDisplay, type FontSource, HStack, type HStackProps, IconDisplay, type IconDisplayProps, IconPicker, type IconPickerProps, type IconPickerSize, type IconSource, type IconValue, Image, type ImageProps, type KeyframeBlock, type KeyframeDefinition, List, type ListProps, type LocalFontDefinition, type LocalFontOptions, Lumio, type LumioConfig, type LumioIdentity, NumberField, type NumberFieldProps, type OverlayTheme, type RenderOptions, Slider, type SliderProps, Text, TextArea, type TextAreaProps, TextField, type TextFieldProps, type TextProps, Toggle, type ToggleProps, type UseAnimationResult, type UseIconPickerOptions, type UseIconPickerResult, type UseLumioActionResult, type UseLumioSoundResult, type UseMutationResult, type UseQueryResult, VStack, type VStackProps, type VisionStyle, WorkerBridge, defineKeyframes, flushKeyframes, getPreset, localFont, useAnimation, useEditorAction, useExtensionContext, useExtensionStorage, useIconPicker, useLumioAction, useLumioConfig, useLumioEvent, useLumioIdentity, useLumioSound, useLumioTheme, useMutation, useQuery, useRealtime, useVisionState };
|
package/dist/index.js
CHANGED
|
@@ -1,8 +1,23 @@
|
|
|
1
|
+
import {
|
|
2
|
+
WorkerBridge,
|
|
3
|
+
getBridge,
|
|
4
|
+
getInitParams
|
|
5
|
+
} from "./chunk-GVAYWB5X.js";
|
|
6
|
+
|
|
1
7
|
// src/core/lumio.tsx
|
|
2
8
|
import { createRoot } from "react-dom/client";
|
|
3
9
|
var RENDER_TIMEOUT_MS = 1e4;
|
|
4
10
|
var hasRendered = false;
|
|
5
11
|
var renderTimeout = null;
|
|
12
|
+
function hostOrigin() {
|
|
13
|
+
try {
|
|
14
|
+
if (typeof document !== "undefined" && document.referrer) {
|
|
15
|
+
return new URL(document.referrer).origin;
|
|
16
|
+
}
|
|
17
|
+
} catch {
|
|
18
|
+
}
|
|
19
|
+
return "*";
|
|
20
|
+
}
|
|
6
21
|
function startRenderTimeout() {
|
|
7
22
|
if (renderTimeout) return;
|
|
8
23
|
renderTimeout = setTimeout(() => {
|
|
@@ -16,7 +31,7 @@ function startRenderTimeout() {
|
|
|
16
31
|
code: "RENDER_TIMEOUT",
|
|
17
32
|
message: "Extension did not render within 10 seconds"
|
|
18
33
|
},
|
|
19
|
-
|
|
34
|
+
hostOrigin()
|
|
20
35
|
);
|
|
21
36
|
}
|
|
22
37
|
}, RENDER_TIMEOUT_MS);
|
|
@@ -39,121 +54,11 @@ var Lumio = {
|
|
|
39
54
|
}
|
|
40
55
|
const root = createRoot(rootElement);
|
|
41
56
|
root.render(element);
|
|
42
|
-
window.parent.postMessage({ type: "READY" },
|
|
57
|
+
window.parent.postMessage({ type: "READY" }, hostOrigin());
|
|
43
58
|
void options;
|
|
44
59
|
}
|
|
45
60
|
};
|
|
46
61
|
|
|
47
|
-
// src/bridge/WorkerBridge.ts
|
|
48
|
-
var WorkerBridge = class {
|
|
49
|
-
notificationHandlers = /* @__PURE__ */ new Map();
|
|
50
|
-
requestHandlers = /* @__PURE__ */ new Map();
|
|
51
|
-
pendingRequests = /* @__PURE__ */ new Map();
|
|
52
|
-
requestCounter = 0;
|
|
53
|
-
requestTimeout;
|
|
54
|
-
messageListener = null;
|
|
55
|
-
destroyed = false;
|
|
56
|
-
constructor(options) {
|
|
57
|
-
this.requestTimeout = options?.requestTimeout ?? 3e4;
|
|
58
|
-
this.messageListener = this.handleMessage.bind(this);
|
|
59
|
-
globalThis.addEventListener("message", this.messageListener);
|
|
60
|
-
}
|
|
61
|
-
notify(method, params) {
|
|
62
|
-
const msg = {
|
|
63
|
-
jsonrpc: "2.0",
|
|
64
|
-
method,
|
|
65
|
-
...params !== void 0 ? { params } : {}
|
|
66
|
-
};
|
|
67
|
-
globalThis.postMessage(msg);
|
|
68
|
-
}
|
|
69
|
-
request(method, params) {
|
|
70
|
-
const id = `req_${++this.requestCounter}`;
|
|
71
|
-
const msg = {
|
|
72
|
-
jsonrpc: "2.0",
|
|
73
|
-
id,
|
|
74
|
-
method,
|
|
75
|
-
...params !== void 0 ? { params } : {}
|
|
76
|
-
};
|
|
77
|
-
return new Promise((resolve, reject) => {
|
|
78
|
-
const timer = setTimeout(() => {
|
|
79
|
-
this.pendingRequests.delete(id);
|
|
80
|
-
reject(new Error("Request timeout"));
|
|
81
|
-
}, this.requestTimeout);
|
|
82
|
-
this.pendingRequests.set(id, { resolve, reject, timer });
|
|
83
|
-
globalThis.postMessage(msg);
|
|
84
|
-
});
|
|
85
|
-
}
|
|
86
|
-
onNotification(method, handler) {
|
|
87
|
-
if (!this.notificationHandlers.has(method)) {
|
|
88
|
-
this.notificationHandlers.set(method, /* @__PURE__ */ new Set());
|
|
89
|
-
}
|
|
90
|
-
this.notificationHandlers.get(method).add(handler);
|
|
91
|
-
return () => {
|
|
92
|
-
this.notificationHandlers.get(method)?.delete(handler);
|
|
93
|
-
};
|
|
94
|
-
}
|
|
95
|
-
onRequest(method, handler) {
|
|
96
|
-
this.requestHandlers.set(method, handler);
|
|
97
|
-
}
|
|
98
|
-
destroy() {
|
|
99
|
-
this.destroyed = true;
|
|
100
|
-
if (this.messageListener) {
|
|
101
|
-
globalThis.removeEventListener("message", this.messageListener);
|
|
102
|
-
this.messageListener = null;
|
|
103
|
-
}
|
|
104
|
-
for (const { timer, reject } of this.pendingRequests.values()) {
|
|
105
|
-
if (timer) clearTimeout(timer);
|
|
106
|
-
reject(new Error("Bridge destroyed"));
|
|
107
|
-
}
|
|
108
|
-
this.pendingRequests.clear();
|
|
109
|
-
this.notificationHandlers.clear();
|
|
110
|
-
this.requestHandlers.clear();
|
|
111
|
-
}
|
|
112
|
-
handleMessage(event) {
|
|
113
|
-
if (this.destroyed) return;
|
|
114
|
-
const data = event.data;
|
|
115
|
-
if (!data || typeof data !== "object" || data.jsonrpc !== "2.0") return;
|
|
116
|
-
if ("id" in data && !("method" in data)) {
|
|
117
|
-
const pending = this.pendingRequests.get(data.id);
|
|
118
|
-
if (pending) {
|
|
119
|
-
this.pendingRequests.delete(data.id);
|
|
120
|
-
if (pending.timer) clearTimeout(pending.timer);
|
|
121
|
-
if (data.error) {
|
|
122
|
-
pending.reject(new Error(data.error.message));
|
|
123
|
-
} else {
|
|
124
|
-
pending.resolve(data.result);
|
|
125
|
-
}
|
|
126
|
-
}
|
|
127
|
-
return;
|
|
128
|
-
}
|
|
129
|
-
if ("id" in data && "method" in data) {
|
|
130
|
-
const handler = this.requestHandlers.get(data.method);
|
|
131
|
-
if (handler) {
|
|
132
|
-
handler(data.params).then((result) => {
|
|
133
|
-
const response = { jsonrpc: "2.0", id: data.id, result };
|
|
134
|
-
globalThis.postMessage(response);
|
|
135
|
-
}).catch((err) => {
|
|
136
|
-
const response = {
|
|
137
|
-
jsonrpc: "2.0",
|
|
138
|
-
id: data.id,
|
|
139
|
-
error: { code: -32603, message: err.message }
|
|
140
|
-
};
|
|
141
|
-
globalThis.postMessage(response);
|
|
142
|
-
});
|
|
143
|
-
}
|
|
144
|
-
return;
|
|
145
|
-
}
|
|
146
|
-
if ("method" in data && !("id" in data)) {
|
|
147
|
-
const handlers = this.notificationHandlers.get(data.method);
|
|
148
|
-
if (handlers) {
|
|
149
|
-
for (const handler of handlers) {
|
|
150
|
-
handler(data.params);
|
|
151
|
-
}
|
|
152
|
-
}
|
|
153
|
-
}
|
|
154
|
-
}
|
|
155
|
-
};
|
|
156
|
-
|
|
157
62
|
// src/components/Box.tsx
|
|
158
63
|
import React from "react";
|
|
159
64
|
function Box({ children, style }) {
|
|
@@ -352,17 +257,6 @@ function EditorChannelRow(props) {
|
|
|
352
257
|
|
|
353
258
|
// src/hooks/useEditorAction.ts
|
|
354
259
|
import { useCallback } from "react";
|
|
355
|
-
|
|
356
|
-
// src/renderer/bridge-context.ts
|
|
357
|
-
var bridgeInstance = null;
|
|
358
|
-
function getBridge() {
|
|
359
|
-
if (!bridgeInstance) {
|
|
360
|
-
bridgeInstance = new WorkerBridge();
|
|
361
|
-
}
|
|
362
|
-
return bridgeInstance;
|
|
363
|
-
}
|
|
364
|
-
|
|
365
|
-
// src/hooks/useEditorAction.ts
|
|
366
260
|
function useEditorAction() {
|
|
367
261
|
const dispatch = useCallback((action, payload) => {
|
|
368
262
|
const bridge = getBridge();
|
|
@@ -473,24 +367,25 @@ import { HOST_METHODS as HOST_METHODS3 } from "@zaflun/lumio-protocol";
|
|
|
473
367
|
var defaultContext = {
|
|
474
368
|
extensionId: null,
|
|
475
369
|
target: null,
|
|
476
|
-
overlayId: null
|
|
477
|
-
interactiveUrl: null
|
|
370
|
+
overlayId: null
|
|
478
371
|
};
|
|
372
|
+
function fromInit(p) {
|
|
373
|
+
return {
|
|
374
|
+
extensionId: p.extensionId ?? null,
|
|
375
|
+
target: p.target ?? null,
|
|
376
|
+
overlayId: p.installId ?? null
|
|
377
|
+
};
|
|
378
|
+
}
|
|
479
379
|
function useExtensionContext() {
|
|
480
|
-
const [context, setContext] = useState4(
|
|
380
|
+
const [context, setContext] = useState4(() => {
|
|
381
|
+
const init = getInitParams();
|
|
382
|
+
return init ? fromInit(init) : defaultContext;
|
|
383
|
+
});
|
|
481
384
|
useEffect3(() => {
|
|
482
385
|
const bridge = getBridge();
|
|
483
386
|
const unsub = bridge.onNotification(
|
|
484
387
|
HOST_METHODS3.LIFECYCLE_INIT,
|
|
485
|
-
(params) =>
|
|
486
|
-
const p = params;
|
|
487
|
-
setContext({
|
|
488
|
-
extensionId: p.extensionId ?? null,
|
|
489
|
-
target: p.target ?? null,
|
|
490
|
-
overlayId: p.installId ?? null,
|
|
491
|
-
interactiveUrl: p.interactiveUrl ?? null
|
|
492
|
-
});
|
|
493
|
-
}
|
|
388
|
+
(params) => setContext(fromInit(params))
|
|
494
389
|
);
|
|
495
390
|
return unsub;
|
|
496
391
|
}, []);
|
|
@@ -501,7 +396,9 @@ function useExtensionContext() {
|
|
|
501
396
|
import { useState as useState5, useEffect as useEffect4 } from "react";
|
|
502
397
|
import { HOST_METHODS as HOST_METHODS4 } from "@zaflun/lumio-protocol";
|
|
503
398
|
function useLumioEvent(eventType) {
|
|
504
|
-
const [eventData, setEventData] = useState5(
|
|
399
|
+
const [eventData, setEventData] = useState5(
|
|
400
|
+
null
|
|
401
|
+
);
|
|
505
402
|
useEffect4(() => {
|
|
506
403
|
const bridge = getBridge();
|
|
507
404
|
const unsub = bridge.onNotification(
|
|
@@ -518,18 +415,46 @@ function useLumioEvent(eventType) {
|
|
|
518
415
|
return eventData;
|
|
519
416
|
}
|
|
520
417
|
|
|
418
|
+
// src/hooks/useRealtime.ts
|
|
419
|
+
import { useEffect as useEffect5, useRef } from "react";
|
|
420
|
+
import { HOST_METHODS as HOST_METHODS5 } from "@zaflun/lumio-protocol";
|
|
421
|
+
function useRealtime(topic, cb) {
|
|
422
|
+
const cbRef = useRef(cb);
|
|
423
|
+
cbRef.current = cb;
|
|
424
|
+
useEffect5(() => {
|
|
425
|
+
const bridge = getBridge();
|
|
426
|
+
return bridge.onNotification(HOST_METHODS5.SERVER_REALTIME, (params) => {
|
|
427
|
+
const p = params;
|
|
428
|
+
if (p && p.topic === topic) {
|
|
429
|
+
cbRef.current(p.payload);
|
|
430
|
+
}
|
|
431
|
+
});
|
|
432
|
+
}, [topic]);
|
|
433
|
+
}
|
|
434
|
+
|
|
521
435
|
// src/hooks/useLumioConfig.ts
|
|
522
|
-
import { useState as useState6, useEffect as
|
|
523
|
-
import { HOST_METHODS as
|
|
436
|
+
import { useState as useState6, useEffect as useEffect6, useCallback as useCallback5 } from "react";
|
|
437
|
+
import { HOST_METHODS as HOST_METHODS6, WORKER_METHODS as WORKER_METHODS3 } from "@zaflun/lumio-protocol";
|
|
524
438
|
function hasShim() {
|
|
525
439
|
return typeof window !== "undefined" && typeof window.__lumio_config === "function";
|
|
526
440
|
}
|
|
441
|
+
function fromInit2(p) {
|
|
442
|
+
return {
|
|
443
|
+
extension_id: p.extensionId,
|
|
444
|
+
install_id: p.installId,
|
|
445
|
+
account_id: p.accountId,
|
|
446
|
+
target: p.target,
|
|
447
|
+
permissions: p.permissions,
|
|
448
|
+
settings: p.settings
|
|
449
|
+
};
|
|
450
|
+
}
|
|
527
451
|
function useLumioConfig() {
|
|
528
452
|
const [config, setConfigState] = useState6(() => {
|
|
529
453
|
if (hasShim()) return window.__lumio_config();
|
|
530
|
-
|
|
454
|
+
const init = getInitParams();
|
|
455
|
+
return init ? fromInit2(init) : {};
|
|
531
456
|
});
|
|
532
|
-
|
|
457
|
+
useEffect6(() => {
|
|
533
458
|
if (hasShim()) {
|
|
534
459
|
const unsub2 = window.__lumio_on_config((newConfig) => {
|
|
535
460
|
setConfigState(newConfig);
|
|
@@ -539,24 +464,14 @@ function useLumioConfig() {
|
|
|
539
464
|
}
|
|
540
465
|
const bridge = getBridge();
|
|
541
466
|
const unsub = bridge.onNotification(
|
|
542
|
-
|
|
543
|
-
(params) =>
|
|
544
|
-
const p = params;
|
|
545
|
-
setConfigState({
|
|
546
|
-
extension_id: p.extensionId,
|
|
547
|
-
install_id: p.installId,
|
|
548
|
-
account_id: p.accountId,
|
|
549
|
-
target: p.target,
|
|
550
|
-
permissions: p.permissions,
|
|
551
|
-
settings: p.settings
|
|
552
|
-
});
|
|
553
|
-
}
|
|
467
|
+
HOST_METHODS6.LIFECYCLE_INIT,
|
|
468
|
+
(params) => setConfigState(fromInit2(params))
|
|
554
469
|
);
|
|
555
470
|
const unsubConfig = bridge.onNotification(
|
|
556
|
-
|
|
471
|
+
HOST_METHODS6.CONFIG_UPDATE,
|
|
557
472
|
(params) => {
|
|
558
473
|
const p = params;
|
|
559
|
-
setConfigState(p);
|
|
474
|
+
setConfigState((prev) => ({ ...prev, ...p }));
|
|
560
475
|
}
|
|
561
476
|
);
|
|
562
477
|
return () => {
|
|
@@ -583,8 +498,8 @@ function useLumioConfig() {
|
|
|
583
498
|
}
|
|
584
499
|
|
|
585
500
|
// src/hooks/useLumioTheme.ts
|
|
586
|
-
import { useState as useState7, useEffect as
|
|
587
|
-
import { HOST_METHODS as
|
|
501
|
+
import { useState as useState7, useEffect as useEffect7 } from "react";
|
|
502
|
+
import { HOST_METHODS as HOST_METHODS7 } from "@zaflun/lumio-protocol";
|
|
588
503
|
var DEFAULT_THEME = {
|
|
589
504
|
colors: {
|
|
590
505
|
primary: "#6366f1",
|
|
@@ -608,11 +523,14 @@ var DEFAULT_THEME = {
|
|
|
608
523
|
spacing: 8
|
|
609
524
|
};
|
|
610
525
|
function useLumioTheme() {
|
|
611
|
-
const [theme, setTheme] = useState7(
|
|
612
|
-
|
|
526
|
+
const [theme, setTheme] = useState7(() => {
|
|
527
|
+
const initTheme = getInitParams()?.theme;
|
|
528
|
+
return initTheme ? { ...DEFAULT_THEME, ...initTheme } : DEFAULT_THEME;
|
|
529
|
+
});
|
|
530
|
+
useEffect7(() => {
|
|
613
531
|
const bridge = getBridge();
|
|
614
532
|
const unsubInit = bridge.onNotification(
|
|
615
|
-
|
|
533
|
+
HOST_METHODS7.LIFECYCLE_INIT,
|
|
616
534
|
(params) => {
|
|
617
535
|
const p = params;
|
|
618
536
|
if (p.theme) {
|
|
@@ -621,7 +539,7 @@ function useLumioTheme() {
|
|
|
621
539
|
}
|
|
622
540
|
);
|
|
623
541
|
const unsubTheme = bridge.onNotification(
|
|
624
|
-
|
|
542
|
+
HOST_METHODS7.THEME_CHANGE,
|
|
625
543
|
(params) => {
|
|
626
544
|
const p = params;
|
|
627
545
|
if (p.theme) {
|
|
@@ -638,27 +556,30 @@ function useLumioTheme() {
|
|
|
638
556
|
}
|
|
639
557
|
|
|
640
558
|
// src/hooks/useLumioIdentity.ts
|
|
641
|
-
import { useState as useState8, useEffect as
|
|
642
|
-
import { HOST_METHODS as
|
|
559
|
+
import { useState as useState8, useEffect as useEffect8 } from "react";
|
|
560
|
+
import { HOST_METHODS as HOST_METHODS8 } from "@zaflun/lumio-protocol";
|
|
643
561
|
var defaultIdentity = {
|
|
644
562
|
userId: null,
|
|
645
563
|
accountId: null,
|
|
646
564
|
role: null
|
|
647
565
|
};
|
|
566
|
+
function fromInit3(p) {
|
|
567
|
+
return {
|
|
568
|
+
userId: p.userId ?? null,
|
|
569
|
+
accountId: p.accountId ?? null,
|
|
570
|
+
role: p.role ?? null
|
|
571
|
+
};
|
|
572
|
+
}
|
|
648
573
|
function useLumioIdentity() {
|
|
649
|
-
const [identity, setIdentity] = useState8(
|
|
650
|
-
|
|
574
|
+
const [identity, setIdentity] = useState8(() => {
|
|
575
|
+
const init = getInitParams();
|
|
576
|
+
return init ? fromInit3(init) : defaultIdentity;
|
|
577
|
+
});
|
|
578
|
+
useEffect8(() => {
|
|
651
579
|
const bridge = getBridge();
|
|
652
580
|
const unsub = bridge.onNotification(
|
|
653
|
-
|
|
654
|
-
(params) =>
|
|
655
|
-
const p = params;
|
|
656
|
-
setIdentity({
|
|
657
|
-
userId: p.userId ?? null,
|
|
658
|
-
accountId: p.accountId ?? null,
|
|
659
|
-
role: p.role ?? null
|
|
660
|
-
});
|
|
661
|
-
}
|
|
581
|
+
HOST_METHODS8.LIFECYCLE_INIT,
|
|
582
|
+
(params) => setIdentity(fromInit3(params))
|
|
662
583
|
);
|
|
663
584
|
return unsub;
|
|
664
585
|
}, []);
|
|
@@ -666,27 +587,27 @@ function useLumioIdentity() {
|
|
|
666
587
|
}
|
|
667
588
|
|
|
668
589
|
// src/hooks/useLumioAction.ts
|
|
669
|
-
import { useState as useState9, useCallback as useCallback6
|
|
590
|
+
import { useState as useState9, useCallback as useCallback6 } from "react";
|
|
591
|
+
import { WORKER_METHODS as WORKER_METHODS4 } from "@zaflun/lumio-protocol";
|
|
670
592
|
function useLumioAction(action) {
|
|
671
593
|
const [data, setData] = useState9(null);
|
|
672
594
|
const [isLoading, setIsLoading] = useState9(false);
|
|
673
595
|
const [error, setError] = useState9(null);
|
|
674
|
-
const actionRef = useRef(action);
|
|
675
|
-
actionRef.current = action;
|
|
676
596
|
const execute = useCallback6(
|
|
677
|
-
(params = {}) => {
|
|
597
|
+
async (params = {}) => {
|
|
678
598
|
setIsLoading(true);
|
|
679
599
|
setError(null);
|
|
680
|
-
const
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
setData(result ?? null);
|
|
600
|
+
const request = { action, params };
|
|
601
|
+
try {
|
|
602
|
+
const result = await getBridge().request(WORKER_METHODS4.ACTION_EXECUTE, request);
|
|
603
|
+
setData(result?.data ?? null);
|
|
684
604
|
setError(null);
|
|
685
|
-
}
|
|
686
|
-
setIsLoading(false);
|
|
605
|
+
} catch (err) {
|
|
687
606
|
setError(err instanceof Error ? err.message : "Unknown error");
|
|
688
607
|
setData(null);
|
|
689
|
-
}
|
|
608
|
+
} finally {
|
|
609
|
+
setIsLoading(false);
|
|
610
|
+
}
|
|
690
611
|
},
|
|
691
612
|
[action]
|
|
692
613
|
);
|
|
@@ -695,27 +616,27 @@ function useLumioAction(action) {
|
|
|
695
616
|
|
|
696
617
|
// src/hooks/useLumioSound.ts
|
|
697
618
|
import { useCallback as useCallback7 } from "react";
|
|
698
|
-
import { WORKER_METHODS as
|
|
619
|
+
import { WORKER_METHODS as WORKER_METHODS5 } from "@zaflun/lumio-protocol";
|
|
699
620
|
function useLumioSound() {
|
|
700
621
|
const playSound = useCallback7(async (soundId, volume) => {
|
|
701
622
|
const bridge = getBridge();
|
|
702
|
-
await bridge.request(
|
|
623
|
+
await bridge.request(WORKER_METHODS5.SOUND_PLAY, { sound_id: soundId, volume });
|
|
703
624
|
}, []);
|
|
704
625
|
const stopSound = useCallback7(async (soundId) => {
|
|
705
626
|
const bridge = getBridge();
|
|
706
|
-
await bridge.request(
|
|
627
|
+
await bridge.request(WORKER_METHODS5.SOUND_STOP, { sound_id: soundId });
|
|
707
628
|
}, []);
|
|
708
629
|
const getSounds = useCallback7(async () => {
|
|
709
630
|
const bridge = getBridge();
|
|
710
|
-
const result = await bridge.request(
|
|
631
|
+
const result = await bridge.request(WORKER_METHODS5.SOUND_LIST, {});
|
|
711
632
|
return result ?? [];
|
|
712
633
|
}, []);
|
|
713
634
|
return { playSound, stopSound, getSounds };
|
|
714
635
|
}
|
|
715
636
|
|
|
716
637
|
// src/hooks/useQuery.ts
|
|
717
|
-
import { useState as useState10, useEffect as
|
|
718
|
-
import { WORKER_METHODS as
|
|
638
|
+
import { useState as useState10, useEffect as useEffect9, useCallback as useCallback8, useRef as useRef2 } from "react";
|
|
639
|
+
import { WORKER_METHODS as WORKER_METHODS6 } from "@zaflun/lumio-protocol";
|
|
719
640
|
function useQuery(functionName, params) {
|
|
720
641
|
const [data, setData] = useState10(null);
|
|
721
642
|
const [isLoading, setIsLoading] = useState10(false);
|
|
@@ -726,7 +647,7 @@ function useQuery(functionName, params) {
|
|
|
726
647
|
setIsLoading(true);
|
|
727
648
|
setError(null);
|
|
728
649
|
const bridge = getBridge();
|
|
729
|
-
bridge.request(
|
|
650
|
+
bridge.request(WORKER_METHODS6.SERVER_QUERY, { fn: functionName, params: params ?? {} }).then((result) => {
|
|
730
651
|
setIsLoading(false);
|
|
731
652
|
setData(result ?? null);
|
|
732
653
|
setError(null);
|
|
@@ -736,7 +657,7 @@ function useQuery(functionName, params) {
|
|
|
736
657
|
setData(null);
|
|
737
658
|
});
|
|
738
659
|
}, [functionName, params]);
|
|
739
|
-
|
|
660
|
+
useEffect9(() => {
|
|
740
661
|
sendQuery();
|
|
741
662
|
}, [sendQuery]);
|
|
742
663
|
return { data, isLoading, error, refetch: sendQuery };
|
|
@@ -744,7 +665,7 @@ function useQuery(functionName, params) {
|
|
|
744
665
|
|
|
745
666
|
// src/hooks/useMutation.ts
|
|
746
667
|
import { useState as useState11, useCallback as useCallback9 } from "react";
|
|
747
|
-
import { WORKER_METHODS as
|
|
668
|
+
import { WORKER_METHODS as WORKER_METHODS7 } from "@zaflun/lumio-protocol";
|
|
748
669
|
function useMutation(functionName) {
|
|
749
670
|
const [data, setData] = useState11(null);
|
|
750
671
|
const [isLoading, setIsLoading] = useState11(false);
|
|
@@ -754,7 +675,7 @@ function useMutation(functionName) {
|
|
|
754
675
|
setIsLoading(true);
|
|
755
676
|
setError(null);
|
|
756
677
|
const bridge = getBridge();
|
|
757
|
-
return bridge.request(
|
|
678
|
+
return bridge.request(WORKER_METHODS7.SERVER_MUTATION, { fn: functionName, params }).then((result) => {
|
|
758
679
|
setIsLoading(false);
|
|
759
680
|
setData(result ?? null);
|
|
760
681
|
setError(null);
|
|
@@ -869,7 +790,7 @@ function getPreset(name) {
|
|
|
869
790
|
}
|
|
870
791
|
|
|
871
792
|
// src/animation/Animated.tsx
|
|
872
|
-
import React31, { useEffect as
|
|
793
|
+
import React31, { useEffect as useEffect10, useRef as useRef3, useState as useState12 } from "react";
|
|
873
794
|
function resolveAnimation(name) {
|
|
874
795
|
if (name === void 0) return void 0;
|
|
875
796
|
try {
|
|
@@ -899,7 +820,7 @@ function Animated({
|
|
|
899
820
|
timerRef.current = null;
|
|
900
821
|
}
|
|
901
822
|
}
|
|
902
|
-
|
|
823
|
+
useEffect10(() => {
|
|
903
824
|
const prevVisible = prevVisibleRef.current;
|
|
904
825
|
prevVisibleRef.current = visible;
|
|
905
826
|
if (visible && !prevVisible) {
|
|
@@ -910,7 +831,7 @@ function Animated({
|
|
|
910
831
|
setPhase("out");
|
|
911
832
|
}
|
|
912
833
|
}, [visible]);
|
|
913
|
-
|
|
834
|
+
useEffect10(() => {
|
|
914
835
|
if (phase === "in") {
|
|
915
836
|
const totalDuration = duration + delay;
|
|
916
837
|
if (loopProp !== void 0) {
|
|
@@ -1007,12 +928,21 @@ function formatFromPath(path) {
|
|
|
1007
928
|
if (lower.endsWith(".woff")) return "woff";
|
|
1008
929
|
return "truetype";
|
|
1009
930
|
}
|
|
931
|
+
var FAMILY_RE = /^[\w -]+$/;
|
|
932
|
+
function escapeCssUrl(src) {
|
|
933
|
+
return src.replace(/[\\"\n\r\f]/g, (c) => `\\${c}`);
|
|
934
|
+
}
|
|
1010
935
|
function buildFontFace(family, src, display, weight, style) {
|
|
936
|
+
if (!FAMILY_RE.test(family)) {
|
|
937
|
+
throw new Error(
|
|
938
|
+
`Invalid font family "${family}": only letters, digits, spaces, "-" and "_" are allowed.`
|
|
939
|
+
);
|
|
940
|
+
}
|
|
1011
941
|
const format = formatFromPath(src);
|
|
1012
942
|
const lines = [
|
|
1013
943
|
"@font-face {",
|
|
1014
944
|
` font-family: "${family}";`,
|
|
1015
|
-
` src: url("${src}") format("${format}");`,
|
|
945
|
+
` src: url("${escapeCssUrl(src)}") format("${format}");`,
|
|
1016
946
|
` font-display: ${display};`
|
|
1017
947
|
];
|
|
1018
948
|
if (weight !== void 0) {
|
|
@@ -1105,5 +1035,6 @@ export {
|
|
|
1105
1035
|
useLumioTheme,
|
|
1106
1036
|
useMutation,
|
|
1107
1037
|
useQuery,
|
|
1038
|
+
useRealtime,
|
|
1108
1039
|
useVisionState
|
|
1109
1040
|
};
|