wenay-react2 1.0.34 → 1.0.36

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.
Files changed (95) hide show
  1. package/README.md +12 -56
  2. package/lib/common/api.d.ts +28 -28
  3. package/lib/common/api.js +31 -31
  4. package/lib/common/src/components/Buttons/MiniButton.d.ts +1 -3
  5. package/lib/common/src/components/Buttons/MiniButton.js +1 -3
  6. package/lib/common/src/components/Dnd/{RNDFunc.d.ts → DragArea.d.ts} +1 -1
  7. package/lib/common/src/components/Dnd/{RNDFunc.js → DragArea.js} +1 -1
  8. package/lib/common/src/components/Dnd/{RNDFunc3.d.ts → FloatingWindow.d.ts} +7 -7
  9. package/lib/common/src/components/Dnd/{RNDFunc3.js → FloatingWindow.js} +10 -10
  10. package/lib/common/src/components/Dnd/OutlineDragDemo.d.ts +1 -0
  11. package/lib/common/src/components/Dnd/{DraggableOutlineDiv.js → OutlineDragDemo.js} +1 -2
  12. package/lib/common/src/components/Dnd/Resizable.js +1 -1
  13. package/lib/common/src/components/Dnd/index.d.ts +3 -3
  14. package/lib/common/src/components/Dnd/index.js +3 -3
  15. package/lib/common/src/components/Input.d.ts +5 -5
  16. package/lib/common/src/components/Input.js +10 -10
  17. package/lib/common/src/components/Menu/RightMenu.d.ts +25 -5
  18. package/lib/common/src/components/Menu/RightMenu.js +27 -19
  19. package/lib/common/src/components/Menu/RightMenuStore.d.ts +2 -2
  20. package/lib/common/src/components/Menu/RightMenuStore.js +1 -1
  21. package/lib/common/src/components/Modal/LeftModal.js +4 -4
  22. package/lib/common/src/components/Modal/Modal.d.ts +11 -17
  23. package/lib/common/src/components/Modal/Modal.js +15 -21
  24. package/lib/common/src/components/Modal/ModalContextProvider.d.ts +0 -6
  25. package/lib/common/src/components/Modal/ModalContextProvider.js +2 -9
  26. package/lib/common/src/components/Other.d.ts +2 -2
  27. package/lib/common/src/components/Other.js +5 -5
  28. package/lib/common/src/components/Parameters.d.ts +3 -3
  29. package/lib/common/src/components/Parameters.js +3 -3
  30. package/lib/common/src/components/{ParametersEngine.d.ts → ParamsEditor.d.ts} +1 -1
  31. package/lib/common/src/components/{ParametersEngine.js → ParamsEditor.js} +10 -10
  32. package/lib/common/src/components/Settings/SettingsDialog.d.ts +4 -4
  33. package/lib/common/src/components/Toolbar/Toolbar.d.ts +50 -37
  34. package/lib/common/src/components/Toolbar/Toolbar.js +60 -23
  35. package/lib/common/src/components/UiSlot/UiSlot.d.ts +3 -3
  36. package/lib/common/src/components/UiSlot/UiSlot.js +6 -6
  37. package/lib/common/src/grid/agGrid4/agGrid4.d.ts +4 -4
  38. package/lib/common/src/grid/agGrid4/agGrid4.js +6 -6
  39. package/lib/common/src/grid/agGrid4/index.d.ts +3 -3
  40. package/lib/common/src/grid/agGrid4/index.js +1 -1
  41. package/lib/common/src/grid/agGrid4/theme.d.ts +3 -3
  42. package/lib/common/src/grid/columnState/CardList.d.ts +11 -0
  43. package/lib/common/src/grid/columnState/CardList.js +28 -0
  44. package/lib/common/src/grid/columnState/ColumnDots.d.ts +9 -0
  45. package/lib/common/src/grid/columnState/ColumnDots.js +121 -0
  46. package/lib/common/src/grid/columnState/ColumnsMenu.d.ts +65 -0
  47. package/lib/common/src/grid/columnState/ColumnsMenu.js +123 -0
  48. package/lib/common/src/grid/columnState/columnState.d.ts +113 -0
  49. package/lib/common/src/grid/columnState/columnState.js +284 -0
  50. package/lib/common/src/grid/columnState/index.d.ts +4 -0
  51. package/lib/common/src/grid/columnState/index.js +4 -0
  52. package/lib/common/src/hooks/index.d.ts +1 -1
  53. package/lib/common/src/hooks/index.js +1 -1
  54. package/lib/common/src/hooks/useKeyboard.d.ts +18 -0
  55. package/lib/common/src/hooks/{useAddDownAnyKey.js → useKeyboard.js} +16 -24
  56. package/lib/common/src/hooks/useObserveStore.d.ts +26 -11
  57. package/lib/common/src/hooks/useObserveStore.js +21 -2
  58. package/lib/common/src/hooks/useOutside.d.ts +12 -19
  59. package/lib/common/src/hooks/useOutside.js +9 -16
  60. package/lib/common/src/hooks/useReorder.d.ts +4 -4
  61. package/lib/common/src/hooks/useReorderBoard.d.ts +15 -15
  62. package/lib/common/src/hooks/useReplay.d.ts +33 -6
  63. package/lib/common/src/hooks/useReplay.js +32 -5
  64. package/lib/common/src/logs/logs.d.ts +3 -3
  65. package/lib/common/src/logs/logs.js +11 -13
  66. package/lib/common/src/logs/{logs3.d.ts → logsContext.d.ts} +4 -4
  67. package/lib/common/src/logs/{logs3.js → logsContext.js} +4 -4
  68. package/lib/common/src/menu/menu.d.ts +16 -16
  69. package/lib/common/src/menu/menu.js +12 -11
  70. package/lib/common/src/menu/menuMouse.d.ts +71 -13
  71. package/lib/common/src/menu/menuMouse.js +189 -21
  72. package/lib/common/src/menu/menuR.d.ts +3 -3
  73. package/lib/common/src/menu/menuR.js +5 -5
  74. package/lib/common/src/styles/styleGrid.d.ts +1 -1
  75. package/lib/common/src/styles/tokens.d.ts +1 -1
  76. package/lib/common/src/styles/tokens.js +1 -1
  77. package/lib/common/src/utils/cache.d.ts +11 -11
  78. package/lib/common/src/utils/cache.js +0 -0
  79. package/lib/common/src/utils/gridRows.d.ts +37 -0
  80. package/lib/common/src/utils/{applyTransactionAsyncUpdate.js → gridRows.js} +6 -38
  81. package/lib/common/src/utils/index.d.ts +2 -2
  82. package/lib/common/src/utils/index.js +2 -2
  83. package/lib/common/src/utils/inputAutoStep.d.ts +2 -2
  84. package/lib/common/src/utils/inputAutoStep.js +26 -37
  85. package/lib/common/src/utils/{mapMemory.d.ts → memoryStore.d.ts} +13 -13
  86. package/lib/common/src/utils/{mapMemory.js → memoryStore.js} +32 -32
  87. package/lib/common/src/utils/observableMap.d.ts +5 -5
  88. package/lib/common/src/utils/observableMap.js +3 -3
  89. package/lib/common/updateBy.js +2 -2
  90. package/lib/style/style.css +3 -3
  91. package/lib/style/tokens.css +1 -1
  92. package/package.json +49 -49
  93. package/lib/common/src/components/Dnd/DraggableOutlineDiv.d.ts +0 -2
  94. package/lib/common/src/hooks/useAddDownAnyKey.d.ts +0 -24
  95. package/lib/common/src/utils/applyTransactionAsyncUpdate.d.ts +0 -53
@@ -1,4 +1,4 @@
1
- import { tReorderItem } from './useReorder';
1
+ import { ReorderItem } from './useReorder';
2
2
  /** useReorderBoard - the columns extension of useReorder: keyed blocks live in
3
3
  * VERTICAL columns (plain consumer divs), one block drags between/within them,
4
4
  * ONE commit on drop. Column "gravity" is pure consumer CSS (justify-content:
@@ -8,19 +8,19 @@ import { tReorderItem } from './useReorder';
8
8
  * drag. Children of a column div must be exactly its items, 1:1, in order.
9
9
  * Same non-goals as useReorder: no nesting, no spans/collision packing, no
10
10
  * autoscroll - that day is a ready-made dnd library. */
11
- export type tBoardPos = {
11
+ export type BoardPosition = {
12
12
  col: string;
13
13
  index: number;
14
14
  };
15
- export type tBoardColumn = {
15
+ export type BoardColumn = {
16
16
  key: string;
17
17
  items: string[];
18
18
  };
19
- export type tReorderBoardOptions = {
19
+ export type ReorderBoardOptions = {
20
20
  /** columns in board order; each column's div children must render items 1:1 */
21
- columns: tBoardColumn[];
21
+ columns: BoardColumn[];
22
22
  /** ONE commit on drop; skipped when nothing moved */
23
- commit: (next: tBoardColumn[]) => void;
23
+ commit: (next: BoardColumn[]) => void;
24
24
  /** false = this key cannot start a drag (default: all can) */
25
25
  canDrag?: (key: string) => boolean;
26
26
  /** hold before the drag starts; default 0 */
@@ -28,12 +28,12 @@ export type tReorderBoardOptions = {
28
28
  /** the block was grabbed */
29
29
  onDragStart?: (e: {
30
30
  key: string;
31
- from: tBoardPos;
31
+ from: BoardPosition;
32
32
  }) => void;
33
33
  /** every pointer move while dragging; position = pointer delta in local px */
34
34
  onDragMove?: (e: {
35
35
  key: string;
36
- over: tBoardPos;
36
+ over: BoardPosition;
37
37
  position: {
38
38
  x: number;
39
39
  y: number;
@@ -42,20 +42,20 @@ export type tReorderBoardOptions = {
42
42
  /** the target slot changed (compare prev.col != over.col for column crossings) */
43
43
  onOverChange?: (e: {
44
44
  key: string;
45
- over: tBoardPos;
46
- prev: tBoardPos | null;
45
+ over: BoardPosition;
46
+ prev: BoardPosition | null;
47
47
  }) => void;
48
48
  /** drop; committed=false when nothing moved (plain click) */
49
49
  onDragEnd?: (e: {
50
50
  key: string;
51
- from: tBoardPos;
52
- over: tBoardPos;
51
+ from: BoardPosition;
52
+ over: BoardPosition;
53
53
  committed: boolean;
54
54
  }) => void;
55
55
  };
56
- export declare function useReorderBoard(o: tReorderBoardOptions): {
56
+ export declare function useReorderBoard(o: ReorderBoardOptions): {
57
57
  columnRef: (col: string) => (el: HTMLElement | null) => void;
58
- item: (key: string) => tReorderItem;
58
+ item: (key: string) => ReorderItem;
59
59
  dragKey: string | null;
60
- over: tBoardPos | null;
60
+ over: BoardPosition | null;
61
61
  };
@@ -1,5 +1,7 @@
1
- import { ObserveAll2, Replay } from "wenay-common2";
2
- type StorePatch = ObserveAll2.StorePatch;
1
+ import { Observe, Replay } from "wenay-common2";
2
+ type StoreDrain = Observe.StoreDrain;
3
+ type StoreEachCtx = Observe.StoreEachCtx;
4
+ type StorePatch = Observe.StorePatch;
3
5
  type ReplayEvent<Z extends any[]> = Replay.ReplayEvent<Z>;
4
6
  type ReplayRemote<Z extends any[]> = Replay.ReplayRemote<Z>;
5
7
  type StaleInfo = Replay.StaleInfo;
@@ -63,14 +65,14 @@ export declare function useReplaySubscribe<Z extends any[]>(remote: ReplayRemote
63
65
  export type UseStoreReplaySyncOptions = UseReplaySubscribeOptions;
64
66
  export type StoreReplaySyncController = ReplaySubscribeController;
65
67
  /**
66
- * Sync an existing mirror store from a store replay line (`ObserveAll2.exposeStoreReplay(...).api.replay`).
67
- * Thin lifecycle wrapper over `ObserveAll2.syncStoreReplay`: the keyframe (root patch) and the
68
+ * Sync an existing mirror store from a store replay line (`Observe.exposeStoreReplay(...).api.replay`).
69
+ * Thin lifecycle wrapper over `Observe.syncStoreReplay`: the keyframe (root patch) and the
68
70
  * patch tail are applied to the store by the library; UI subscribes to the store as usual
69
71
  * (useStoreNode/useStoreSelect).
70
72
  */
71
- export declare function useStoreReplaySync<T extends object>(store: ObserveAll2.Store<T> | null | undefined, remote: ReplayRemote<[StorePatch]> | null | undefined, options?: UseStoreReplaySyncOptions): StoreReplaySyncController;
73
+ export declare function useStoreReplaySync<T extends object>(store: Observe.Store<T> | null | undefined, remote: ReplayRemote<[StorePatch]> | null | undefined, options?: UseStoreReplaySyncOptions): StoreReplaySyncController;
72
74
  export type StoreReplayMirrorController<T extends object> = StoreReplaySyncController & {
73
- readonly store: ObserveAll2.Store<T>;
75
+ readonly store: Observe.Store<T>;
74
76
  };
75
77
  /**
76
78
  * Convenience: create a local mirror store and keep it synced from a store replay line.
@@ -78,6 +80,31 @@ export type StoreReplayMirrorController<T extends object> = StoreReplaySyncContr
78
80
  * so reconnect is a journal tail, not a keyframe. A new `remote` recreates the store.
79
81
  */
80
82
  export declare function useStoreReplayMirror<T extends object>(remote: ReplayRemote<[StorePatch]> | null | undefined, initial: T, options?: UseStoreReplaySyncOptions): StoreReplayMirrorController<T>;
83
+ export type UseStoreReplayEachOptions<T extends object> = UseStoreReplaySyncOptions & {
84
+ /**
85
+ * Seed of the internal mirror store. Creation-time only (a later identity change does nothing).
86
+ * Reconnect after a FULL unmount: pass the saved snapshot together with `since`
87
+ * ({since: prev.seq(), initial: prev.store.snapshot()}) — the tail lands ON TOP of the previous
88
+ * state; a fresh empty mirror would not converge.
89
+ */
90
+ initial?: T;
91
+ /** Drain of the internal mirror store — the coalescing window of the per-key feed. Creation-time only. */
92
+ drain?: StoreDrain;
93
+ };
94
+ /**
95
+ * Per-key fold over a store replay line — React counterpart of `Observe.syncStoreReplayEach`
96
+ * (internal mirror store + syncStoreReplay + store.each()). cb fires once per CHANGED top-level
97
+ * key per drain window with the current value; the first delivery is the keyframe EXPANDED per
98
+ * key; (key, undefined) = key deleted — cold start / reconnect are not special cases for per-key
99
+ * consumers (grid rows, canvas layers, ...). The fold target should live outside React state.
100
+ *
101
+ * Unlike the library one-call (a fresh store per call), the mirror here lives in a ref: within
102
+ * one mounted component every resubscribe (StrictMode double-effect, restart(), enabled toggling,
103
+ * staleMs/policy change) reconnects by tail ON TOP of the kept state — no snapshot/initial dance.
104
+ * A new `remote` identity recreates the store (fresh keyframe). Direct reads / extra
105
+ * subscriptions: controller.store (useStoreNode/useStoreKeys work on it as usual).
106
+ */
107
+ export declare function useStoreReplayEach<T extends object>(remote: ReplayRemote<[StorePatch]> | null | undefined, cb: (key: string, value: T[keyof T] | undefined, ctx: StoreEachCtx) => void, options?: UseStoreReplayEachOptions<T>): StoreReplayMirrorController<T>;
81
108
  export type UseReplayFrameOptions = {
82
109
  /** Pull period, ms. Default 300. */
83
110
  intervalMs?: number;
@@ -1,5 +1,6 @@
1
1
  import { useCallback, useEffect, useMemo, useRef, useState } from "react";
2
- import { ObserveAll2, Replay } from "wenay-common2";
2
+ import { Observe, Replay } from "wenay-common2";
3
+ import { useStoreEach } from "./useObserveStore";
3
4
  /**
4
5
  * React bridge over the Replay stack (snapshot + sequenced delta line) of wenay-common2.
5
6
  *
@@ -111,8 +112,8 @@ export function useReplaySubscribe(remote, cb, options = {}) {
111
112
  return useMemo(() => ({ ready, error, stale, seq, lastTs, restart }), [ready, error, stale, seq, lastTs, restart]);
112
113
  }
113
114
  /**
114
- * Sync an existing mirror store from a store replay line (`ObserveAll2.exposeStoreReplay(...).api.replay`).
115
- * Thin lifecycle wrapper over `ObserveAll2.syncStoreReplay`: the keyframe (root patch) and the
115
+ * Sync an existing mirror store from a store replay line (`Observe.exposeStoreReplay(...).api.replay`).
116
+ * Thin lifecycle wrapper over `Observe.syncStoreReplay`: the keyframe (root patch) and the
116
117
  * patch tail are applied to the store by the library; UI subscribes to the store as usual
117
118
  * (useStoreNode/useStoreSelect).
118
119
  */
@@ -138,7 +139,7 @@ export function useStoreReplaySync(store, remote, options = {}) {
138
139
  setError(null);
139
140
  if (staleMs === undefined)
140
141
  setStale(false); // see useReplaySubscribe: stale re-syncs from common2, no reset-to-false flicker
141
- const off = ObserveAll2.syncStoreReplay(store, remote, {
142
+ const off = Observe.syncStoreReplay(store, remote, {
142
143
  since: seqRef.current,
143
144
  policy,
144
145
  hint: hintRef.current,
@@ -195,12 +196,38 @@ export function useStoreReplaySync(store, remote, options = {}) {
195
196
  export function useStoreReplayMirror(remote, initial, options = {}) {
196
197
  const storeRef = useRef(null);
197
198
  if (!storeRef.current || storeRef.current.remote !== remote) {
198
- storeRef.current = { remote, store: ObserveAll2.createStore(initial) };
199
+ storeRef.current = { remote, store: Observe.createStore(initial) };
199
200
  }
200
201
  const store = storeRef.current.store;
201
202
  const sync = useStoreReplaySync(store, remote, options);
202
203
  return useMemo(() => ({ ...sync, store }), [sync, store]);
203
204
  }
205
+ /**
206
+ * Per-key fold over a store replay line — React counterpart of `Observe.syncStoreReplayEach`
207
+ * (internal mirror store + syncStoreReplay + store.each()). cb fires once per CHANGED top-level
208
+ * key per drain window with the current value; the first delivery is the keyframe EXPANDED per
209
+ * key; (key, undefined) = key deleted — cold start / reconnect are not special cases for per-key
210
+ * consumers (grid rows, canvas layers, ...). The fold target should live outside React state.
211
+ *
212
+ * Unlike the library one-call (a fresh store per call), the mirror here lives in a ref: within
213
+ * one mounted component every resubscribe (StrictMode double-effect, restart(), enabled toggling,
214
+ * staleMs/policy change) reconnects by tail ON TOP of the kept state — no snapshot/initial dance.
215
+ * A new `remote` identity recreates the store (fresh keyframe). Direct reads / extra
216
+ * subscriptions: controller.store (useStoreNode/useStoreKeys work on it as usual).
217
+ */
218
+ export function useStoreReplayEach(remote, cb, options = {}) {
219
+ const { initial, drain, ...syncOptions } = options;
220
+ const storeRef = useRef(null);
221
+ if (!storeRef.current || storeRef.current.remote !== remote) {
222
+ storeRef.current = { remote, store: Observe.createStore((initial ?? {}), drain !== undefined ? { drain } : undefined) };
223
+ }
224
+ const store = storeRef.current.store;
225
+ // each BEFORE sync: effects run in hook-call order, so the per-key subscriber already exists
226
+ // when the keyframe applies to the store (the expansion is not missed)
227
+ useStoreEach(store, cb, { enabled: syncOptions.enabled });
228
+ const sync = useStoreReplaySync(store, remote, syncOptions);
229
+ return useMemo(() => ({ ...sync, store }), [sync, store]);
230
+ }
204
231
  /**
205
232
  * Pull a replay line at YOUR pace (the frame model of common2): a timer around
206
233
  * `remote.frame(seq, hint)` — the server condenses the tail via the line's `frame` lambda
@@ -1,5 +1,5 @@
1
1
  import { Params } from "wenay-common2";
2
- type tLogsInput<T extends object> = T & {
2
+ type LogInput<T extends object> = T & {
3
3
  id: string;
4
4
  var?: number;
5
5
  time: Date;
@@ -43,7 +43,7 @@ export declare function getLogsApi<T extends object = {}>(setting: {
43
43
  limitPer: number;
44
44
  varMin?: number;
45
45
  }): {
46
- addLogs(a: tLogsInput<T>): void;
46
+ addLogs(a: LogInput<T>): void;
47
47
  params: {
48
48
  def: () => {
49
49
  minVarLogs: {
@@ -160,7 +160,7 @@ export declare function PageLogs({ update }: {
160
160
  export declare function MessageEventLogs({ zIndex }: {
161
161
  zIndex?: number;
162
162
  }): import("react/jsx-runtime").JSX.Element;
163
- export declare function PageLogs2({ update }: {
163
+ export declare function LogsPage({ update }: {
164
164
  update?: number;
165
165
  }): import("react/jsx-runtime").JSX.Element;
166
166
  export {};
@@ -3,9 +3,9 @@ import { AgGridReact } from "ag-grid-react";
3
3
  import { useCallback, useEffect, useRef } from "react";
4
4
  import { copyToClipboard, Params, timeLocalToStr_hhmmss } from "wenay-common2";
5
5
  import { renderBy, updateBy } from "../../updateBy";
6
- import { mouseMenuApi } from "../menu/menuMouse";
7
- import { staticGetAdd } from "../utils/mapMemory";
8
- import { ParametersReact } from "../components/ParametersEngine";
6
+ import { contextMenu } from "../menu/menuMouse";
7
+ import { memoryGetOrCreate } from "../utils/memoryStore";
8
+ import { ParamsEditor } from "../components/ParamsEditor";
9
9
  const cashLogs = new Map();
10
10
  const datumConst = {
11
11
  map: cashLogs,
@@ -22,7 +22,7 @@ const getSettingLogs = () => ({
22
22
  const settingLogs = { params: Params.GetSimpleParams(getSettingLogs()) };
23
23
  // varMin - minimum importance
24
24
  export function getLogsApi(setting) {
25
- const datum = staticGetAdd("settingLogs", settingLogs);
25
+ const datum = memoryGetOrCreate("settingLogs", settingLogs);
26
26
  function addToArr(arr, data, limit) {
27
27
  arr.unshift(data);
28
28
  if (arr.length > limit)
@@ -55,8 +55,8 @@ export function getLogsApi(setting) {
55
55
  }
56
56
  export const logsApi = getLogsApi({ limitPer: 500 });
57
57
  function InputSettingLogs({}) {
58
- const datum = staticGetAdd("settingLogs", settingLogs);
59
- return _jsx(ParametersReact
58
+ const datum = memoryGetOrCreate("settingLogs", settingLogs);
59
+ return _jsx(ParamsEditor
60
60
  // @ts-ignore
61
61
  , {
62
62
  // @ts-ignore
@@ -69,7 +69,7 @@ export function PageLogs({ update }) {
69
69
  const datumFull = datumConst;
70
70
  const rowData = [...datumFull.map.values()].flat();
71
71
  const datum = datumMiniConst;
72
- const setting = staticGetAdd("settingLogs", settingLogs);
72
+ const setting = memoryGetOrCreate("settingLogs", settingLogs);
73
73
  const apiGrid = useRef(null);
74
74
  useEffect(() => {
75
75
  apiGrid.current?.api.sizeColumnsToFit();
@@ -160,10 +160,8 @@ export function PageLogs({ update }) {
160
160
  filter: true,
161
161
  wrapText: true,
162
162
  }, headerHeight: 30, rowHeight: 26, autoSizePadding: 1, rowData: rowData, columnDefs: columns, onCellMouseDown: (e) => {
163
- // @ts-ignore
164
- if (e.event?.button == 2) {
165
- // copyToClipboard(e.value)
166
- mouseMenuApi.map.set("sym", [
163
+ if (e.event instanceof MouseEvent && e.event.button == 2) {
164
+ contextMenu.openAt(e.event, [
167
165
  {
168
166
  name: "copy", onClick: () => { copyToClipboard(e.value); }
169
167
  }
@@ -189,7 +187,7 @@ function Message({ logs }) {
189
187
  const tt = {};
190
188
  let r = 0;
191
189
  export function MessageEventLogs({ zIndex }) {
192
- const setting = staticGetAdd("settingLogs", settingLogs);
190
+ const setting = memoryGetOrCreate("settingLogs", settingLogs);
193
191
  updateBy(tt);
194
192
  updateBy(datumMiniConst, () => {
195
193
  const last = datumMiniConst.last[0];
@@ -222,7 +220,7 @@ const pages = [
222
220
  { name: "setting", key: "InputSettingLogs", page: InputSettingLogs },
223
221
  ];
224
222
  const map = Object.fromEntries(pages.map(e => [e.key, e.page]));
225
- export function PageLogs2({ update }) {
223
+ export function LogsPage({ update }) {
226
224
  const datum = defPageBase;
227
225
  updateBy(datum);
228
226
  const Page = map[datum.keyPage];
@@ -3,14 +3,14 @@ import React from 'react';
3
3
  * 1. Log types
4
4
  * -----------------------------
5
5
  */
6
- export interface tLogsInput<T extends object = {}> {
6
+ export interface LogInput<T extends object = {}> {
7
7
  id: string;
8
8
  var?: number;
9
9
  time: Date;
10
10
  txt: string;
11
11
  [key: string]: any;
12
12
  }
13
- export interface tLogs<T extends object = {}> extends tLogsInput<T> {
13
+ export interface LogEntry<T extends object = {}> extends LogInput<T> {
14
14
  num: number;
15
15
  }
16
16
  /** -----------------------------
@@ -18,8 +18,8 @@ export interface tLogs<T extends object = {}> extends tLogsInput<T> {
18
18
  * -----------------------------
19
19
  */
20
20
  interface LogsContextValue {
21
- logs: tLogs[];
22
- addLog: (input: tLogsInput) => void;
21
+ logs: LogEntry[];
22
+ addLog: (input: LogInput) => void;
23
23
  minVarLogs: number;
24
24
  setMinVarLogs: (value: number) => void;
25
25
  minVarMessage: number;
@@ -2,11 +2,11 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import { createContext, useContext, useCallback, useEffect, useMemo, useRef, useState } from 'react';
3
3
  import { AgGridReact } from 'ag-grid-react';
4
4
  /** -----------------------------
5
- * 2. staticGetAdd function -
5
+ * 2. memoryGetOrCreate function -
6
6
  * loads and saves data in localStorage.
7
7
  * -----------------------------
8
8
  */
9
- function staticGetAdd(key, defaultValue) {
9
+ function memoryGetOrCreate(key, defaultValue) {
10
10
  try {
11
11
  const stored = localStorage.getItem(key);
12
12
  // If localStorage has no value, write defaultValue
@@ -32,7 +32,7 @@ function staticGetAdd(key, defaultValue) {
32
32
  const LogsContext = createContext(null);
33
33
  export function LogsProvider({ children }) {
34
34
  // 4.1. Load settings from localStorage once (lazy init: the provider rerenders on every addLog)
35
- const [savedSettings] = useState(() => staticGetAdd("logSettings", {
35
+ const [savedSettings] = useState(() => memoryGetOrCreate("logSettings", {
36
36
  minVarLogs: 0,
37
37
  minVarMessage: 0,
38
38
  timeShow: 2,
@@ -42,7 +42,7 @@ export function LogsProvider({ children }) {
42
42
  // only settings are, but logs can be saved too if needed)
43
43
  const [logs, setLogs] = useState([]);
44
44
  const counterRef = useRef(0);
45
- // 4.3. Settings themselves, initialized from staticGetAdd output
45
+ // 4.3. Settings themselves, initialized from memoryGetOrCreate output
46
46
  const [minVarLogs, setMinVarLogs] = useState(savedSettings.minVarLogs);
47
47
  const [minVarMessage, setMinVarMessage] = useState(savedSettings.minVarMessage);
48
48
  const [timeShow, setTimeShow] = useState(savedSettings.timeShow);
@@ -2,22 +2,22 @@ import React, { ReactElement } from 'react';
2
2
  /*******************************************************
3
3
  * Menu data types
4
4
  *******************************************************/
5
- export type tMenuReactStrictly<T = any> = {
5
+ export type MenuItemStrict<T = any> = {
6
6
  name: string | ((status?: T) => string);
7
7
  getStatus?: (() => T) | null;
8
8
  onClick?: ((e: any) => void | undefined | null | ((void | undefined | null | Promise<any> | (() => Promise<any>))[]) | Promise<any>) | null;
9
9
  active?: (() => boolean) | null;
10
10
  status?: boolean;
11
- next?: (() => (tMenuReact<any> | false)[] | Promise<(tMenuReact<any> | false)[]>) | null;
11
+ next?: (() => (MenuItem<any> | false)[] | Promise<(MenuItem<any> | false)[]>) | null;
12
12
  func?: (() => React.ReactElement | Promise<React.ReactElement>) | null;
13
- onFocus?: (() => tMenuReact<any>[] | Promise<tMenuReact<any>[]>) | null;
13
+ onFocus?: (() => MenuItem<any>[] | Promise<MenuItem<any>[]>) | null;
14
14
  menuElement?: typeof MenuElement;
15
15
  };
16
- export type tMenuReact<T = any> = tMenuReactStrictly<T> | false | null | undefined;
16
+ export type MenuItem<T = any> = MenuItemStrict<T> | false | null | undefined;
17
17
  /*******************************************************
18
18
  * Helper type
19
19
  *******************************************************/
20
- type tCounters = {
20
+ type MenuProgressCounters = {
21
21
  ok?: number;
22
22
  error?: number;
23
23
  count?: number;
@@ -25,20 +25,20 @@ type tCounters = {
25
25
  /*******************************************************
26
26
  * Displays counter/progress with animation and ok/error counts
27
27
  *******************************************************/
28
- declare function TimeNum({ data }: {
29
- data: tCounters;
28
+ declare function MenuProgress({ data }: {
29
+ data: MenuProgressCounters;
30
30
  }): ReactElement;
31
31
  /*******************************************************
32
32
  * Main menu element with onClick and counters
33
33
  *******************************************************/
34
34
  declare function MenuElement({ data: item, toLeft, className, update, }: {
35
- data: Pick<tMenuReactStrictly, "onClick" | "active" | "name" | "getStatus">;
35
+ data: Pick<MenuItemStrict, "onClick" | "active" | "name" | "getStatus">;
36
36
  toLeft: boolean;
37
37
  className?: (active?: boolean) => string;
38
38
  update: () => void;
39
39
  }): ReactElement;
40
40
  /*******************************************************
41
- * MenuBase renders the popup menu with support for
41
+ * Menu renders the popup menu with support for
42
42
  * nested submenus and their state management.
43
43
  *
44
44
  * @param {Object} props - Component props.
@@ -47,7 +47,7 @@ declare function MenuElement({ data: item, toLeft, className, update, }: {
47
47
  * @param {number} props.coordinate.y - Y coordinate for menu placement.
48
48
  * @param {boolean} [props.coordinate.toLeft=false] - Whether the menu should be shifted left.
49
49
  * @param {number} [props.coordinate.left=0] - Additional left offset when the menu has nested items.
50
- * @param {tMenuReactStrictly[]} props.data - Array of objects describing menu items.
50
+ * @param {MenuItemStrict[]} props.data - Array of objects describing menu items.
51
51
  * @param {number} [props.zIndex] - Menu z-index for overlap visibility.
52
52
  * @param {Function} [props.menu] - Function that generates a custom React element for the whole menu.
53
53
  * @param {Function} [props.menuElement] - Function that generates a custom React element for one menu item.
@@ -55,10 +55,10 @@ declare function MenuElement({ data: item, toLeft, className, update, }: {
55
55
  *
56
56
  * @returns {ReactElement} Visual menu element.
57
57
  */
58
- type MenuBaseProps = {
59
- menu?: (arr: tMenuReact[]) => ReactElement;
60
- menuElement?: (item: tMenuReact) => ReactElement;
61
- data: tMenuReact[];
58
+ type MenuProps = {
59
+ menu?: (arr: MenuItem[]) => ReactElement;
60
+ menuElement?: (item: MenuItem) => ReactElement;
61
+ data: MenuItem[];
62
62
  zIndex?: number;
63
63
  className?: (active?: boolean) => string;
64
64
  coordinate?: {
@@ -68,5 +68,5 @@ type MenuBaseProps = {
68
68
  left?: number;
69
69
  };
70
70
  };
71
- export declare function MenuBase({ coordinate, data, zIndex, menu, className, menuElement, }: MenuBaseProps): ReactElement;
72
- export { TimeNum, MenuElement };
71
+ export declare function Menu({ coordinate, data, zIndex, menu, className, menuElement, }: MenuProps): ReactElement;
72
+ export { MenuProgress, MenuElement };
@@ -1,10 +1,10 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import { useEffect, useLayoutEffect, useMemo, useRef, useState, } from 'react';
3
- import { PromiseArrayListen, sleepAsync } from "wenay-common2";
3
+ import { promiseProgress, sleepAsync } from "wenay-common2";
4
4
  /*******************************************************
5
5
  * Displays counter/progress with animation and ok/error counts
6
6
  *******************************************************/
7
- function TimeNum({ data }) {
7
+ function MenuProgress({ data }) {
8
8
  const [count, setCount] = useState(0);
9
9
  const formatLabel = () => {
10
10
  if (!data.ok && !data.error)
@@ -54,7 +54,7 @@ function MenuElement({ data: item, toLeft, className, update, }) {
54
54
  // If this is an array of tasks, promises, or functions
55
55
  if (Array.isArray(result)) {
56
56
  const tasks = result.filter(Boolean);
57
- const pa = PromiseArrayListen(tasks); // External helper function
57
+ const pa = promiseProgress(tasks);
58
58
  setProgress({});
59
59
  unsubOk.current?.();
60
60
  unsubErr.current?.();
@@ -71,8 +71,9 @@ function MenuElement({ data: item, toLeft, className, update, }) {
71
71
  setProgress(null);
72
72
  }
73
73
  };
74
- unsubOk.current = pa.listenOk((data, i, countOk, countError, count) => onTick(countOk, countError, count));
75
- unsubErr.current = pa.listenError((error, i, countOk, countError, count) => onTick(countOk, countError, count));
74
+ unsubOk.current = pa.onOk((data, i, countOk, countError, count) => onTick(countOk, countError, count));
75
+ unsubErr.current = pa.onError((error, i, countOk, countError, count) => onTick(countOk, countError, count));
76
+ void pa.allSettled();
76
77
  }
77
78
  // If this is a single promise
78
79
  else if (result instanceof Promise) {
@@ -108,7 +109,7 @@ function MenuElement({ data: item, toLeft, className, update, }) {
108
109
  }
109
110
  }, children: _jsxs("div", { className: "toLine", children: [typeof item.name === "string"
110
111
  ? item.name
111
- : item.name(item.getStatus?.()), progress && _jsx(TimeNum, { data: progress })] }) }));
112
+ : item.name(item.getStatus?.()), progress && _jsx(MenuProgress, { data: progress })] }) }));
112
113
  }
113
114
  const MenuItemWrapper = ({ item, index, update, className, isLeftAligned, leftPos, menuElement, fullArray, }) => {
114
115
  const [childMenu, setChildMenu] = useState([]);
@@ -186,24 +187,24 @@ const MenuItemWrapper = ({ item, index, update, className, isLeftAligned, leftPo
186
187
  data: item,
187
188
  className,
188
189
  update,
189
- }) ?? (_jsx(MenuElement, { toLeft: isLeftAligned, data: item, className: className, update: update })), _jsxs("div", { children: [item.status && childMenu.length > 0 && (_jsx("div", { style: { position: "relative" }, children: _jsx(MenuBase, { data: childMenu, coordinate: {
190
+ }) ?? (_jsx(MenuElement, { toLeft: isLeftAligned, data: item, className: className, update: update })), _jsxs("div", { children: [item.status && childMenu.length > 0 && (_jsx("div", { style: { position: "relative" }, children: _jsx(Menu, { data: childMenu, coordinate: {
190
191
  x: 3,
191
192
  y: 0,
192
193
  toLeft: isLeftAligned,
193
194
  left: leftPos,
194
- } }) })), item.status && asyncFuncElement && (_jsx("div", { style: { position: "relative" }, children: _jsx(MenuBase, { menu: () => asyncFuncElement, data: [], coordinate: {
195
+ } }) })), item.status && asyncFuncElement && (_jsx("div", { style: { position: "relative" }, children: _jsx(Menu, { menu: () => asyncFuncElement, data: [], coordinate: {
195
196
  x: 3,
196
197
  y: 0,
197
198
  toLeft: isLeftAligned,
198
199
  left: leftPos,
199
- } }) })), item.status && onFocusMenu.length > 0 && (_jsx("div", { style: { position: "relative" }, children: _jsx(MenuBase, { data: onFocusMenu, coordinate: {
200
+ } }) })), item.status && onFocusMenu.length > 0 && (_jsx("div", { style: { position: "relative" }, children: _jsx(Menu, { data: onFocusMenu, coordinate: {
200
201
  x: 3,
201
202
  y: 0,
202
203
  toLeft: isLeftAligned,
203
204
  left: leftPos,
204
205
  } }) }))] })] }));
205
206
  };
206
- export function MenuBase({ coordinate = { x: 0, y: 0, toLeft: false, left: 0 }, data, zIndex, menu, className, menuElement, }) {
207
+ export function Menu({ coordinate = { x: 0, y: 0, toLeft: false, left: 0 }, data, zIndex, menu, className, menuElement, }) {
207
208
  const [, forceUpdate] = useState(false);
208
209
  const update = () => forceUpdate((p) => !p);
209
210
  const refMenu = useRef(null);
@@ -251,4 +252,4 @@ export function MenuBase({ coordinate = { x: 0, y: 0, toLeft: false, left: 0 },
251
252
  ? menu(dataMemo)
252
253
  : dataMemo.map((item, i, arr) => (_jsx(MenuItemWrapper, { item: item, index: i, update: update, className: className, isLeftAligned: isLeftAligned, leftPos: leftPos, menuElement: menuElement, fullArray: dataMemo }, typeof item.name === "string" ? item.name : i))) }));
253
254
  }
254
- export { TimeNum, MenuElement };
255
+ export { MenuProgress, MenuElement };
@@ -1,7 +1,62 @@
1
- import { MenuBase, tMenuReact } from "./menu";
2
- export declare const mouseMenuApi: {
1
+ import React from "react";
2
+ import { Menu, MenuItem, MenuItemStrict } from "./menu";
3
+ export type ContextMenuPoint = {
4
+ x: number;
5
+ y: number;
6
+ };
7
+ export type ContextMenuAnchor = ContextMenuPoint | {
8
+ clientX: number;
9
+ clientY: number;
10
+ target?: EventTarget | null;
11
+ preventDefault?: () => void;
12
+ stopPropagation?: () => void;
13
+ };
14
+ export type ContextMenuState = {
15
+ open: boolean;
16
+ items: MenuItemStrict[];
17
+ point: ContextMenuPoint;
18
+ source?: string;
19
+ layerId?: string;
20
+ seq: number;
21
+ };
22
+ export type ContextMenuLayerProps = {
23
+ children: React.ReactElement;
24
+ zIndex?: number;
25
+ other?: () => MenuItem[];
26
+ statusOn?: boolean;
27
+ onUnClick?: (e: boolean) => void;
28
+ onConsume?: () => void;
29
+ className?: (active?: boolean) => string;
30
+ };
31
+ export declare function createContextMenu(data?: {
32
+ name?: string;
33
+ }): {
34
+ bb: (b?: boolean) => boolean | undefined;
35
+ readonly map: Map<string, MenuItem[]>;
36
+ readonly menuMouse: {
37
+ name: string;
38
+ readonly value: {
39
+ status: boolean;
40
+ clicks: number;
41
+ };
42
+ };
43
+ getState: () => ContextMenuState;
44
+ subscribe: (cb: () => void) => () => void;
45
+ openAt: (anchor: ContextMenuAnchor, items: readonly MenuItem[] | null | undefined, opts?: {
46
+ source?: string;
47
+ layerId?: string;
48
+ }) => boolean;
49
+ openAtPoint: (point: ContextMenuPoint, items: readonly MenuItem[] | null | undefined, opts?: {
50
+ source?: string;
51
+ layerId?: string;
52
+ }) => boolean;
53
+ close: () => void;
54
+ Layer: ({ children, other, statusOn, onUnClick, onConsume, zIndex, className }: ContextMenuLayerProps) => import("react/jsx-runtime").JSX.Element;
55
+ MenuView: typeof Menu;
56
+ };
57
+ export declare const contextMenu: {
3
58
  bb: (b?: boolean) => boolean | undefined;
4
- readonly map: Map<string, tMenuReact[]>;
59
+ readonly map: Map<string, MenuItem[]>;
5
60
  readonly menuMouse: {
6
61
  name: string;
7
62
  readonly value: {
@@ -9,14 +64,17 @@ export declare const mouseMenuApi: {
9
64
  clicks: number;
10
65
  };
11
66
  };
12
- ReactMouse: (agr: Parameters<({ children, other, statusOn, onUnClick, onConsume, zIndex, className }: {
13
- children: React.ReactElement;
14
- zIndex?: number;
15
- other?: () => (tMenuReact)[];
16
- statusOn?: boolean;
17
- onUnClick?: (e: boolean) => void;
18
- onConsume?: () => void;
19
- className?: (active?: boolean) => string;
20
- }) => import("react/jsx-runtime").JSX.Element>[0]) => import("react/jsx-runtime").JSX.Element;
21
- ReactMenu: typeof MenuBase;
67
+ getState: () => ContextMenuState;
68
+ subscribe: (cb: () => void) => () => void;
69
+ openAt: (anchor: ContextMenuAnchor, items: readonly MenuItem[] | null | undefined, opts?: {
70
+ source?: string;
71
+ layerId?: string;
72
+ }) => boolean;
73
+ openAtPoint: (point: ContextMenuPoint, items: readonly MenuItem[] | null | undefined, opts?: {
74
+ source?: string;
75
+ layerId?: string;
76
+ }) => boolean;
77
+ close: () => void;
78
+ Layer: ({ children, other, statusOn, onUnClick, onConsume, zIndex, className }: ContextMenuLayerProps) => import("react/jsx-runtime").JSX.Element;
79
+ MenuView: typeof Menu;
22
80
  };