@arcanejs/toolkit-frontend 0.11.0 → 0.12.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.
@@ -23,6 +23,10 @@ type StageConnectionState = {
23
23
  type StageContextData = {
24
24
  sendMessage: (<M extends proto$1.AnyClientComponentMessage>(msg: M) => void) | null;
25
25
  call: (<Namespace extends string, P, Action extends string & keyof P>(msg: proto$1.CallForPair<Namespace, P, Action>) => Promise<proto$1.ReturnForPair<P, Action>>) | null;
26
+ upload: (<M extends proto$1.AnyClientComponentCallUpload>(msg: Omit<M, 'requestId'>, data: Blob | ReadableStream<Uint8Array>) => Promise<void>) | null;
27
+ download: (<M extends proto$1.AnyClientComponentCallDownload>(msg: Omit<M, 'requestId'>) => Promise<ReadableStream<Uint8Array<ArrayBuffer>>>) | null;
28
+ addNotificationListener: ((listener: (msg: proto$1.BaseNotificationMessage<string, string>) => void) => void) | null;
29
+ removeNotificationListener: ((listener: (msg: proto$1.BaseNotificationMessage<string, string>) => void) => void) | null;
26
30
  renderComponent: (info: proto$1.AnyComponentProto) => ReactElement;
27
31
  connectionUuid: string | null;
28
32
  connection: StageConnectionState;
@@ -35,6 +39,7 @@ type StageContextData = {
35
39
  reconnect: () => void;
36
40
  };
37
41
  declare const StageContext: React.Context<StageContextData>;
42
+ declare const useNotificationHandler: <T extends proto$1.BaseNotificationMessage<string, string>>(typeGuard: (msg: proto$1.BaseNotificationMessage<string, string>) => msg is T, handler: (msg: T) => void, dependencyList: unknown[]) => void;
38
43
 
39
44
  interface Props$7 {
40
45
  className?: string;
@@ -98,4 +103,4 @@ declare const Timeline: FC<Props>;
98
103
 
99
104
  declare const CORE_FRONTEND_COMPONENT_RENDERER: FrontendComponentRenderer;
100
105
 
101
- export { Button, CORE_FRONTEND_COMPONENT_RENDERER, Group, GroupStateWrapper, Label, NestedContent, Rect, SliderButton, type StageConnectionState, StageContext, type StageContextData, Switch, Tabs, TextInput, Timeline };
106
+ export { Button, CORE_FRONTEND_COMPONENT_RENDERER, Group, GroupStateWrapper, Label, NestedContent, Rect, SliderButton, type StageConnectionState, StageContext, type StageContextData, Switch, Tabs, TextInput, Timeline, useNotificationHandler };
@@ -23,6 +23,10 @@ type StageConnectionState = {
23
23
  type StageContextData = {
24
24
  sendMessage: (<M extends proto$1.AnyClientComponentMessage>(msg: M) => void) | null;
25
25
  call: (<Namespace extends string, P, Action extends string & keyof P>(msg: proto$1.CallForPair<Namespace, P, Action>) => Promise<proto$1.ReturnForPair<P, Action>>) | null;
26
+ upload: (<M extends proto$1.AnyClientComponentCallUpload>(msg: Omit<M, 'requestId'>, data: Blob | ReadableStream<Uint8Array>) => Promise<void>) | null;
27
+ download: (<M extends proto$1.AnyClientComponentCallDownload>(msg: Omit<M, 'requestId'>) => Promise<ReadableStream<Uint8Array<ArrayBuffer>>>) | null;
28
+ addNotificationListener: ((listener: (msg: proto$1.BaseNotificationMessage<string, string>) => void) => void) | null;
29
+ removeNotificationListener: ((listener: (msg: proto$1.BaseNotificationMessage<string, string>) => void) => void) | null;
26
30
  renderComponent: (info: proto$1.AnyComponentProto) => ReactElement;
27
31
  connectionUuid: string | null;
28
32
  connection: StageConnectionState;
@@ -35,6 +39,7 @@ type StageContextData = {
35
39
  reconnect: () => void;
36
40
  };
37
41
  declare const StageContext: React.Context<StageContextData>;
42
+ declare const useNotificationHandler: <T extends proto$1.BaseNotificationMessage<string, string>>(typeGuard: (msg: proto$1.BaseNotificationMessage<string, string>) => msg is T, handler: (msg: T) => void, dependencyList: unknown[]) => void;
38
43
 
39
44
  interface Props$7 {
40
45
  className?: string;
@@ -98,4 +103,4 @@ declare const Timeline: FC<Props>;
98
103
 
99
104
  declare const CORE_FRONTEND_COMPONENT_RENDERER: FrontendComponentRenderer;
100
105
 
101
- export { Button, CORE_FRONTEND_COMPONENT_RENDERER, Group, GroupStateWrapper, Label, NestedContent, Rect, SliderButton, type StageConnectionState, StageContext, type StageContextData, Switch, Tabs, TextInput, Timeline };
106
+ export { Button, CORE_FRONTEND_COMPONENT_RENDERER, Group, GroupStateWrapper, Label, NestedContent, Rect, SliderButton, type StageConnectionState, StageContext, type StageContextData, Switch, Tabs, TextInput, Timeline, useNotificationHandler };
@@ -18,6 +18,11 @@ var _react = require('react'); var _react2 = _interopRequireDefault(_react);
18
18
 
19
19
  // src/components/context.ts
20
20
 
21
+
22
+
23
+
24
+
25
+
21
26
  var StageContext = _react.createContext.call(void 0,
22
27
  new Proxy({}, {
23
28
  get: () => {
@@ -25,6 +30,31 @@ var StageContext = _react.createContext.call(void 0,
25
30
  }
26
31
  })
27
32
  );
33
+ var useNotificationHandler = (typeGuard, handler, dependencyList) => {
34
+ const { addNotificationListener, removeNotificationListener } = _react.useContext.call(void 0, StageContext);
35
+ if (!addNotificationListener || !removeNotificationListener) {
36
+ throw new Error(
37
+ "useNotificationHandler must be used within a StageContext"
38
+ );
39
+ }
40
+ const callback = _react.useCallback.call(void 0, handler, dependencyList);
41
+ _react.useEffect.call(void 0, () => {
42
+ const listener = (msg) => {
43
+ if (typeGuard(msg)) {
44
+ callback(msg);
45
+ }
46
+ };
47
+ addNotificationListener(listener);
48
+ return () => {
49
+ removeNotificationListener(listener);
50
+ };
51
+ }, [
52
+ addNotificationListener,
53
+ removeNotificationListener,
54
+ typeGuard,
55
+ callback
56
+ ]);
57
+ };
28
58
 
29
59
  // src/components/button.tsx
30
60
  var _jsxruntime = require('react/jsx-runtime');
@@ -924,4 +954,5 @@ var CORE_FRONTEND_COMPONENT_RENDERER = {
924
954
 
925
955
 
926
956
 
927
- exports.Button = Button; exports.CORE_FRONTEND_COMPONENT_RENDERER = CORE_FRONTEND_COMPONENT_RENDERER; exports.Group = Group; exports.GroupStateWrapper = GroupStateWrapper; exports.Label = Label; exports.NestedContent = NestedContent; exports.Rect = Rect; exports.SliderButton = SliderButton; exports.StageContext = StageContext; exports.Switch = Switch; exports.Tabs = Tabs; exports.TextInput = TextInput; exports.Timeline = Timeline; exports.code = _chunkBBUHASWZjs.core_exports;
957
+
958
+ exports.Button = Button; exports.CORE_FRONTEND_COMPONENT_RENDERER = CORE_FRONTEND_COMPONENT_RENDERER; exports.Group = Group; exports.GroupStateWrapper = GroupStateWrapper; exports.Label = Label; exports.NestedContent = NestedContent; exports.Rect = Rect; exports.SliderButton = SliderButton; exports.StageContext = StageContext; exports.Switch = Switch; exports.Tabs = Tabs; exports.TextInput = TextInput; exports.Timeline = Timeline; exports.code = _chunkBBUHASWZjs.core_exports; exports.useNotificationHandler = useNotificationHandler;
@@ -17,7 +17,12 @@ import { isCoreComponent } from "@arcanejs/protocol/core";
17
17
  import React from "react";
18
18
 
19
19
  // src/components/context.ts
20
- import { createContext } from "react";
20
+ import {
21
+ createContext,
22
+ useCallback,
23
+ useContext,
24
+ useEffect
25
+ } from "react";
21
26
  var StageContext = createContext(
22
27
  new Proxy({}, {
23
28
  get: () => {
@@ -25,6 +30,31 @@ var StageContext = createContext(
25
30
  }
26
31
  })
27
32
  );
33
+ var useNotificationHandler = (typeGuard, handler, dependencyList) => {
34
+ const { addNotificationListener, removeNotificationListener } = useContext(StageContext);
35
+ if (!addNotificationListener || !removeNotificationListener) {
36
+ throw new Error(
37
+ "useNotificationHandler must be used within a StageContext"
38
+ );
39
+ }
40
+ const callback = useCallback(handler, dependencyList);
41
+ useEffect(() => {
42
+ const listener = (msg) => {
43
+ if (typeGuard(msg)) {
44
+ callback(msg);
45
+ }
46
+ };
47
+ addNotificationListener(listener);
48
+ return () => {
49
+ removeNotificationListener(listener);
50
+ };
51
+ }, [
52
+ addNotificationListener,
53
+ removeNotificationListener,
54
+ typeGuard,
55
+ callback
56
+ ]);
57
+ };
28
58
 
29
59
  // src/components/button.tsx
30
60
  import { jsx, jsxs } from "react/jsx-runtime";
@@ -94,7 +124,7 @@ var Button = (props) => {
94
124
 
95
125
  // src/components/group.tsx
96
126
  import React3, {
97
- useContext,
127
+ useContext as useContext2,
98
128
  useState
99
129
  } from "react";
100
130
 
@@ -162,8 +192,8 @@ var GroupStateWrapper = ({ openByDefault, children }) => {
162
192
  return /* @__PURE__ */ jsx3(GroupStateContext.Provider, { value: { isCollapsed, toggleCollapsed }, children });
163
193
  };
164
194
  var Group = ({ className, info }) => {
165
- const groupState = useContext(GroupStateContext);
166
- const { renderComponent, sendMessage } = useContext(StageContext);
195
+ const groupState = useContext2(GroupStateContext);
196
+ const { renderComponent, sendMessage } = useContext2(StageContext);
167
197
  const [editingTitle, setEditingTitle] = useState(false);
168
198
  const children = /* @__PURE__ */ jsx3(
169
199
  "div",
@@ -343,7 +373,7 @@ var Rect = ({ className, info }) => /* @__PURE__ */ jsx5(
343
373
  );
344
374
 
345
375
  // src/components/slider-button.tsx
346
- import React4, { useCallback } from "react";
376
+ import React4, { useCallback as useCallback2 } from "react";
347
377
  import { jsx as jsx6, jsxs as jsxs3 } from "react/jsx-runtime";
348
378
  var OPEN_SLIDER_WIDTH = 400;
349
379
  var SLIDER_PADDING = 15;
@@ -374,7 +404,7 @@ var SliderButton = ({ info, className }) => {
374
404
  }
375
405
  return NUMBER_FORMATTER.format(value2);
376
406
  };
377
- const sendValue = useCallback(
407
+ const sendValue = useCallback2(
378
408
  (value2) => sendMessage?.({
379
409
  type: "component-message",
380
410
  namespace: "core",
@@ -384,7 +414,7 @@ var SliderButton = ({ info, className }) => {
384
414
  }),
385
415
  [sendMessage, info.key]
386
416
  );
387
- const sanitizeValue = useCallback(
417
+ const sanitizeValue = useCallback2(
388
418
  (value2) => {
389
419
  const i = Math.round((value2 - info.min) / info.step);
390
420
  const v = i * info.step + info.min;
@@ -392,13 +422,13 @@ var SliderButton = ({ info, className }) => {
392
422
  },
393
423
  [info.min, info.max, info.step]
394
424
  );
395
- const getNewValue = useCallback(
425
+ const getNewValue = useCallback2(
396
426
  (startValue, diff) => {
397
427
  return sanitizeValue((startValue || 0) + diff);
398
428
  },
399
429
  [sanitizeValue]
400
430
  );
401
- const getCurrentInputValue = useCallback(
431
+ const getCurrentInputValue = useCallback2(
402
432
  (e) => {
403
433
  const float = parseFloat(e.currentTarget.value);
404
434
  return sanitizeValue(isNaN(float) ? info.value || 0 : float);
@@ -766,12 +796,12 @@ var Tabs = (props) => {
766
796
  };
767
797
 
768
798
  // src/components/text-input.tsx
769
- import React7, { useEffect } from "react";
799
+ import React7, { useEffect as useEffect2 } from "react";
770
800
  import { jsx as jsx9 } from "react/jsx-runtime";
771
801
  var TextInput = ({ className, info }) => {
772
802
  const { sendMessage } = React7.useContext(StageContext);
773
803
  const ref = React7.useRef(null);
774
- useEffect(() => {
804
+ useEffect2(() => {
775
805
  if (ref.current && ref.current.value !== info.value) {
776
806
  ref.current.value = info.value;
777
807
  }
@@ -801,17 +831,17 @@ var TextInput = ({ className, info }) => {
801
831
  };
802
832
 
803
833
  // src/components/timeline.tsx
804
- import React8, { useContext as useContext2, useEffect as useEffect2, useState as useState3 } from "react";
834
+ import React8, { useContext as useContext3, useEffect as useEffect3, useState as useState3 } from "react";
805
835
  import { jsx as jsx10, jsxs as jsxs6 } from "react/jsx-runtime";
806
836
  var Timeline = (props) => {
807
837
  const { className, info } = props;
808
- const { timeDifferenceMs } = useContext2(StageContext);
838
+ const { timeDifferenceMs } = useContext3(StageContext);
809
839
  const frameState = React8.useRef({
810
840
  animationFrame: -1,
811
841
  state: null
812
842
  });
813
843
  const [currentTimeMillis, setCurrentTimeMillis] = useState3(0);
814
- useEffect2(() => {
844
+ useEffect3(() => {
815
845
  frameState.current.state = info.state;
816
846
  const recalculateCurrentTimeMillis = () => {
817
847
  if (frameState.current.state !== info.state) {
@@ -923,5 +953,6 @@ export {
923
953
  Tabs,
924
954
  TextInput,
925
955
  Timeline,
926
- core_exports as code
956
+ core_exports as code,
957
+ useNotificationHandler
927
958
  };
@@ -42,6 +42,6 @@ declare const useColorSchemePreferences: () => {
42
42
  colorSchemePreference: "auto" | "dark" | "light";
43
43
  setColorSchemePreference: (newPreference: ColorSchemePreference) => void;
44
44
  };
45
- declare const usePreferredColorScheme: () => 'dark' | 'light';
45
+ declare const usePreferredColorScheme: () => "dark" | "light";
46
46
 
47
47
  export { type PressableOnClickListener, VALID_COLOR_SCHEME_PREFS, calculateClass, cn, initialiseListeners, switchToMouseMode, switchToTouchMode, trackTouch, useColorSchemePreferences, useLongPressable, usePreferredColorScheme, usePressable };
@@ -42,6 +42,6 @@ declare const useColorSchemePreferences: () => {
42
42
  colorSchemePreference: "auto" | "dark" | "light";
43
43
  setColorSchemePreference: (newPreference: ColorSchemePreference) => void;
44
44
  };
45
- declare const usePreferredColorScheme: () => 'dark' | 'light';
45
+ declare const usePreferredColorScheme: () => "dark" | "light";
46
46
 
47
47
  export { type PressableOnClickListener, VALID_COLOR_SCHEME_PREFS, calculateClass, cn, initialiseListeners, switchToMouseMode, switchToTouchMode, trackTouch, useColorSchemePreferences, useLongPressable, usePreferredColorScheme, usePressable };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@arcanejs/toolkit-frontend",
3
- "version": "0.11.0",
3
+ "version": "0.12.0",
4
4
  "private": false,
5
5
  "description": "Library of the frontend react components used to render the @arcanejs Toolkit",
6
6
  "keywords": [],
@@ -72,16 +72,16 @@
72
72
  "eslint-plugin-better-tailwindcss": "^4.2.0",
73
73
  "tailwindcss": "^4.1.13",
74
74
  "tsup": "^8.1.0",
75
- "typescript": "^5.3.3",
76
- "@arcanejs/eslint-config": "^0.0.0",
77
- "@arcanejs/typescript-config": "^0.0.0"
75
+ "typescript": "^5.7",
76
+ "@arcanejs/typescript-config": "^0.0.0",
77
+ "@arcanejs/eslint-config": "^0.0.0"
78
78
  },
79
79
  "dependencies": {
80
80
  "clsx": "^2.1.1",
81
81
  "react": "^19.2.0",
82
82
  "react-dom": "^19.2.0",
83
83
  "tailwind-merge": "^3.5.0",
84
- "@arcanejs/protocol": "^0.8.0"
84
+ "@arcanejs/protocol": "^0.9.0"
85
85
  },
86
86
  "files": [
87
87
  "dist"