@buoy-gg/jotai 7.0.41 → 7.0.42
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 +11 -80
- package/lib/commonjs/index.js +1 -112
- package/lib/commonjs/jotai/components/JotaiAtomBrowser.js +1 -199
- package/lib/commonjs/jotai/components/JotaiAtomChangeItem.js +1 -95
- package/lib/commonjs/jotai/components/JotaiAtomDetailContent.js +1 -715
- package/lib/commonjs/jotai/components/JotaiAtomValueDetailContent.js +1 -444
- package/lib/commonjs/jotai/components/JotaiEventFilterView.js +1 -43
- package/lib/commonjs/jotai/components/JotaiIcon.js +1 -18
- package/lib/commonjs/jotai/components/JotaiModal.js +1 -743
- package/lib/commonjs/jotai/hooks/useJotaiAtomChanges.js +1 -69
- package/lib/commonjs/jotai/sync/jotaiSyncAdapter.js +1 -306
- package/lib/commonjs/jotai/types/index.js +1 -1
- package/lib/commonjs/jotai/utils/jotaiStateStore.js +1 -321
- package/lib/commonjs/jotai/utils/snapshotProvider.js +1 -215
- package/lib/commonjs/jotai/utils/testIDs.js +1 -90
- package/lib/commonjs/jotai/utils/watchAtoms.js +1 -143
- package/lib/commonjs/jotai/utils/writeSemantics.js +1 -47
- package/lib/commonjs/preset.js +1 -90
- package/lib/module/index.js +1 -85
- package/lib/module/jotai/components/JotaiAtomBrowser.js +1 -195
- package/lib/module/jotai/components/JotaiAtomChangeItem.js +1 -91
- package/lib/module/jotai/components/JotaiAtomDetailContent.js +1 -710
- package/lib/module/jotai/components/JotaiAtomValueDetailContent.js +1 -442
- package/lib/module/jotai/components/JotaiEventFilterView.js +1 -39
- package/lib/module/jotai/components/JotaiIcon.js +1 -11
- package/lib/module/jotai/components/JotaiModal.js +1 -738
- package/lib/module/jotai/hooks/useJotaiAtomChanges.js +1 -65
- package/lib/module/jotai/sync/jotaiSyncAdapter.js +1 -303
- package/lib/module/jotai/types/index.js +1 -1
- package/lib/module/jotai/utils/jotaiStateStore.js +1 -317
- package/lib/module/jotai/utils/snapshotProvider.js +1 -214
- package/lib/module/jotai/utils/testIDs.js +1 -82
- package/lib/module/jotai/utils/watchAtoms.js +1 -138
- package/lib/module/jotai/utils/writeSemantics.js +1 -43
- package/lib/module/preset.js +1 -87
- package/lib/web/index.mjs +2 -3
- package/package.json +3 -3
- package/lib/typescript/index.d.ts.map +0 -1
- package/lib/typescript/jotai/components/JotaiAtomBrowser.d.ts.map +0 -1
- package/lib/typescript/jotai/components/JotaiAtomChangeItem.d.ts.map +0 -1
- package/lib/typescript/jotai/components/JotaiAtomDetailContent.d.ts.map +0 -1
- package/lib/typescript/jotai/components/JotaiAtomValueDetailContent.d.ts.map +0 -1
- package/lib/typescript/jotai/components/JotaiEventFilterView.d.ts.map +0 -1
- package/lib/typescript/jotai/components/JotaiIcon.d.ts.map +0 -1
- package/lib/typescript/jotai/components/JotaiModal.d.ts.map +0 -1
- package/lib/typescript/jotai/hooks/useJotaiAtomChanges.d.ts.map +0 -1
- package/lib/typescript/jotai/sync/jotaiSyncAdapter.d.ts.map +0 -1
- package/lib/typescript/jotai/types/index.d.ts.map +0 -1
- package/lib/typescript/jotai/utils/jotaiStateStore.d.ts.map +0 -1
- package/lib/typescript/jotai/utils/snapshotProvider.d.ts.map +0 -1
- package/lib/typescript/jotai/utils/testIDs.d.ts.map +0 -1
- package/lib/typescript/jotai/utils/watchAtoms.d.ts.map +0 -1
- package/lib/typescript/jotai/utils/writeSemantics.d.ts.map +0 -1
- package/lib/typescript/preset.d.ts.map +0 -1
|
@@ -1,143 +1 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
|
|
3
|
-
Object.defineProperty(exports, "__esModule", {
|
|
4
|
-
value: true
|
|
5
|
-
});
|
|
6
|
-
exports.isAtomWatched = isAtomWatched;
|
|
7
|
-
exports.watchAtoms = watchAtoms;
|
|
8
|
-
exports.watchDefaultStoreAtoms = watchDefaultStoreAtoms;
|
|
9
|
-
var _vanilla = require("jotai/vanilla");
|
|
10
|
-
var _jotaiStateStore = require("./jotaiStateStore");
|
|
11
|
-
var _writeSemantics = require("./writeSemantics");
|
|
12
|
-
/**
|
|
13
|
-
* Buoy Jotai DevTools — Atom instrumentation
|
|
14
|
-
*
|
|
15
|
-
* watchAtoms() — RECOMMENDED. Pass a Jotai store and a named atom map.
|
|
16
|
-
* Uses store.sub() to observe each atom externally. Never touches atom internals.
|
|
17
|
-
*
|
|
18
|
-
* watchDefaultStoreAtoms() — Convenience wrapper that uses getDefaultStore().
|
|
19
|
-
*/
|
|
20
|
-
|
|
21
|
-
/** Any Jotai atom — alias for Atom<unknown> for readability */
|
|
22
|
-
|
|
23
|
-
/** Minimal store shape — what Jotai's createStore() / getDefaultStore() returns */
|
|
24
|
-
|
|
25
|
-
/**
|
|
26
|
-
* Watch a set of Jotai atoms for value changes.
|
|
27
|
-
*
|
|
28
|
-
* Pass a Jotai store and an object mapping display names to atoms.
|
|
29
|
-
* Uses store.sub() to observe each atom — never modifies atom internals.
|
|
30
|
-
*
|
|
31
|
-
* @example
|
|
32
|
-
* ```tsx
|
|
33
|
-
* import { getDefaultStore } from 'jotai';
|
|
34
|
-
* import { watchAtoms } from '@buoy-gg/jotai';
|
|
35
|
-
* import { countAtom } from './atoms/count';
|
|
36
|
-
* import { authAtom } from './atoms/auth';
|
|
37
|
-
*
|
|
38
|
-
* watchAtoms(getDefaultStore(), {
|
|
39
|
-
* countAtom,
|
|
40
|
-
* authAtom,
|
|
41
|
-
* });
|
|
42
|
-
* ```
|
|
43
|
-
*
|
|
44
|
-
* @param store - Jotai store (from createStore() or getDefaultStore())
|
|
45
|
-
* @param atoms - Object mapping display labels to Jotai atoms
|
|
46
|
-
* @param options - Optional configuration
|
|
47
|
-
* @returns Cleanup function that removes all subscriptions
|
|
48
|
-
*/
|
|
49
|
-
function watchAtoms(store, atoms, options) {
|
|
50
|
-
const enabled = options?.enabled !== false;
|
|
51
|
-
const cleanups = [];
|
|
52
|
-
for (const [label, atom] of Object.entries(atoms)) {
|
|
53
|
-
// Skip if already watched under this label
|
|
54
|
-
const atomAny = atom;
|
|
55
|
-
const watchedKey = Symbol.for(`@@buoy-jotai/watched/${label}`);
|
|
56
|
-
if (atomAny[watchedKey]) continue;
|
|
57
|
-
atomAny[watchedKey] = true;
|
|
58
|
-
let prevValue;
|
|
59
|
-
try {
|
|
60
|
-
prevValue = store.get(atom);
|
|
61
|
-
} catch {
|
|
62
|
-
prevValue = undefined;
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
// Register the atom for the browser view. A setter is captured only when
|
|
66
|
-
// the store supports `set` AND the atom itself is writable (has a `write`
|
|
67
|
-
// function — primitive atoms get a default one, read-only derived atoms
|
|
68
|
-
// have none). Deriveds used to get a setter that threw inside jotai at
|
|
69
|
-
// set time; now they're correctly reported as read-only up front.
|
|
70
|
-
const isWritable = typeof atom.write === "function";
|
|
71
|
-
const setter = store.set && isWritable ? value => {
|
|
72
|
-
store.set(atom, value);
|
|
73
|
-
} : undefined;
|
|
74
|
-
_jotaiStateStore.jotaiStateStore.registerAtom(label, () => {
|
|
75
|
-
try {
|
|
76
|
-
return store.get(atom);
|
|
77
|
-
} catch {
|
|
78
|
-
return undefined;
|
|
79
|
-
}
|
|
80
|
-
}, setter,
|
|
81
|
-
// "value" = jotai's shared defaultWrite (a primitive atom: store.set
|
|
82
|
-
// stores the value). "action" = a custom write receiving the value as
|
|
83
|
-
// its argument — still writable, but the editor says so.
|
|
84
|
-
isWritable ? (0, _writeSemantics.classifyAtomWrite)(atom) : undefined);
|
|
85
|
-
|
|
86
|
-
// Record initial value
|
|
87
|
-
if (enabled) {
|
|
88
|
-
_jotaiStateStore.jotaiStateStore.addAtomChange({
|
|
89
|
-
atomLabel: label,
|
|
90
|
-
prevValue: undefined,
|
|
91
|
-
nextValue: prevValue,
|
|
92
|
-
category: "initial"
|
|
93
|
-
});
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
// Subscribe to future changes
|
|
97
|
-
const unsubscribe = store.sub(atom, () => {
|
|
98
|
-
try {
|
|
99
|
-
const nextValue = store.get(atom);
|
|
100
|
-
_jotaiStateStore.jotaiStateStore.addAtomChange({
|
|
101
|
-
atomLabel: label,
|
|
102
|
-
prevValue,
|
|
103
|
-
nextValue,
|
|
104
|
-
category: "write"
|
|
105
|
-
});
|
|
106
|
-
prevValue = nextValue;
|
|
107
|
-
} catch {
|
|
108
|
-
// Silently catch — our bug must never propagate into the store
|
|
109
|
-
}
|
|
110
|
-
});
|
|
111
|
-
cleanups.push(() => {
|
|
112
|
-
unsubscribe();
|
|
113
|
-
delete atomAny[watchedKey];
|
|
114
|
-
_jotaiStateStore.jotaiStateStore.unregisterAtom(label);
|
|
115
|
-
});
|
|
116
|
-
}
|
|
117
|
-
return () => cleanups.forEach(fn => fn());
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
/**
|
|
121
|
-
* Watch atoms using Jotai's default store (no Provider setup required).
|
|
122
|
-
*
|
|
123
|
-
* Convenience wrapper around watchAtoms() — auto-imports getDefaultStore.
|
|
124
|
-
*
|
|
125
|
-
* @example
|
|
126
|
-
* ```tsx
|
|
127
|
-
* import { watchDefaultStoreAtoms } from '@buoy-gg/jotai';
|
|
128
|
-
* import { countAtom, authAtom } from './atoms';
|
|
129
|
-
*
|
|
130
|
-
* watchDefaultStoreAtoms({ countAtom, authAtom });
|
|
131
|
-
* ```
|
|
132
|
-
*/
|
|
133
|
-
function watchDefaultStoreAtoms(atoms, options) {
|
|
134
|
-
const store = (0, _vanilla.getDefaultStore)();
|
|
135
|
-
return watchAtoms(store, atoms, options);
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
/**
|
|
139
|
-
* Check if an atom label is currently being watched
|
|
140
|
-
*/
|
|
141
|
-
function isAtomWatched(label) {
|
|
142
|
-
return _jotaiStateStore.jotaiStateStore.getAtom(label) !== undefined;
|
|
143
|
-
}
|
|
1
|
+
"use strict";Object.defineProperty(exports,"__esModule",{value:true});exports.isAtomWatched=isAtomWatched;exports.watchAtoms=watchAtoms;exports.watchDefaultStoreAtoms=watchDefaultStoreAtoms;var _vanilla=require("jotai/vanilla");var _jotaiStateStore=require("./jotaiStateStore");var _writeSemantics=require("./writeSemantics");function watchAtoms(t,n,i){const d=i?.enabled!==false;const s=[];for(const[a,e]of Object.entries(n)){const c=e;const u=Symbol.for(`@@buoy-jotai/watched/${a}`);if(c[u])continue;c[u]=true;let o;try{o=t.get(e)}catch{o=void 0}const l=typeof e.write==="function";const f=t.set&&l?r=>{t.set(e,r)}:void 0;_jotaiStateStore.jotaiStateStore.registerAtom(a,()=>{try{return t.get(e)}catch{return void 0}},f,l?(0,_writeSemantics.classifyAtomWrite)(e):void 0);if(d){_jotaiStateStore.jotaiStateStore.addAtomChange({atomLabel:a,prevValue:void 0,nextValue:o,category:"initial"})}const S=t.sub(e,()=>{try{const r=t.get(e);_jotaiStateStore.jotaiStateStore.addAtomChange({atomLabel:a,prevValue:o,nextValue:r,category:"write"});o=r}catch{}});s.push(()=>{S();delete c[u];_jotaiStateStore.jotaiStateStore.unregisterAtom(a)})}return()=>s.forEach(a=>a())}function watchDefaultStoreAtoms(t,n){const i=(0,_vanilla.getDefaultStore)();return watchAtoms(i,t,n)}function isAtomWatched(t){return _jotaiStateStore.jotaiStateStore.getAtom(t)!==void 0}
|
|
@@ -1,47 +1 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
|
|
3
|
-
Object.defineProperty(exports, "__esModule", {
|
|
4
|
-
value: true
|
|
5
|
-
});
|
|
6
|
-
exports.classifyAtomWrite = classifyAtomWrite;
|
|
7
|
-
var _vanilla = require("jotai/vanilla");
|
|
8
|
-
/**
|
|
9
|
-
* What does `store.set(atom, x)` DO with x?
|
|
10
|
-
*
|
|
11
|
-
* jotai's `atom(initialValue)` gives every primitive atom the SAME shared
|
|
12
|
-
* `defaultWrite` function (see jotai/src/vanilla/atom.ts): it stores x as the
|
|
13
|
-
* atom's new value (or calls it with the previous value when x is a
|
|
14
|
-
* function). Any other `write` is app code — `atomWithReducer` receives
|
|
15
|
-
* ACTIONS, `atomWithStorage` persists as a side effect, a custom write can do
|
|
16
|
-
* anything — so a raw value handed to `store.set` may not mean "set to this".
|
|
17
|
-
*
|
|
18
|
-
* The tool's editor needs that distinction to be honest: a "value" atom edits
|
|
19
|
-
* like plain data; an "action" atom is still writable (the MCP `setAtom` and
|
|
20
|
-
* Time Machine restore already write to them) but the editor says what the
|
|
21
|
-
* write actually does.
|
|
22
|
-
*
|
|
23
|
-
* Detection: a probe primitive atom exposes this jotai instance's
|
|
24
|
-
* `defaultWrite`; identity match is exact. The `toString` fallback covers an
|
|
25
|
-
* app that somehow bundles a second jotai copy (its atoms carry a different —
|
|
26
|
-
* but textually identical — defaultWrite instance). An unrecognized write
|
|
27
|
-
* classifies as "action", which only makes the editor more cautious.
|
|
28
|
-
*/
|
|
29
|
-
|
|
30
|
-
const probe = (0, _vanilla.atom)(null);
|
|
31
|
-
const DEFAULT_WRITE = probe.write;
|
|
32
|
-
const DEFAULT_WRITE_SOURCE = typeof DEFAULT_WRITE === "function" ? String(DEFAULT_WRITE) : null;
|
|
33
|
-
|
|
34
|
-
/** Classify a writable atom's write. Call only when `atom.write` exists. */
|
|
35
|
-
function classifyAtomWrite(candidate) {
|
|
36
|
-
const atomLike = candidate;
|
|
37
|
-
const write = atomLike?.write;
|
|
38
|
-
if (typeof write !== "function") return "action";
|
|
39
|
-
if (write === DEFAULT_WRITE) return "value";
|
|
40
|
-
// Dual-copy fallback: a primitive atom from another jotai instance holds
|
|
41
|
-
// its own value (`init` present) and its write's source is the library's
|
|
42
|
-
// defaultWrite verbatim.
|
|
43
|
-
if (atomLike !== null && "init" in atomLike && DEFAULT_WRITE_SOURCE !== null && String(write) === DEFAULT_WRITE_SOURCE) {
|
|
44
|
-
return "value";
|
|
45
|
-
}
|
|
46
|
-
return "action";
|
|
47
|
-
}
|
|
1
|
+
"use strict";Object.defineProperty(exports,"__esModule",{value:true});exports.classifyAtomWrite=classifyAtomWrite;var _vanilla=require("jotai/vanilla");const probe=(0,_vanilla.atom)(null);const DEFAULT_WRITE=probe.write;const DEFAULT_WRITE_SOURCE=typeof DEFAULT_WRITE==="function"?String(DEFAULT_WRITE):null;function classifyAtomWrite(n){const t=n;const e=t?.write;if(typeof e!=="function")return"action";if(e===DEFAULT_WRITE)return"value";if(t!==null&&"init"in t&&DEFAULT_WRITE_SOURCE!==null&&String(e)===DEFAULT_WRITE_SOURCE){return"value"}return"action"}
|
package/lib/commonjs/preset.js
CHANGED
|
@@ -1,90 +1 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
|
|
3
|
-
Object.defineProperty(exports, "__esModule", {
|
|
4
|
-
value: true
|
|
5
|
-
});
|
|
6
|
-
exports.jotaiToolPreset = exports.createJotaiTool = void 0;
|
|
7
|
-
var _JotaiModal = require("./jotai/components/JotaiModal");
|
|
8
|
-
var _JotaiIcon = require("./jotai/components/JotaiIcon");
|
|
9
|
-
var _sharedUi = require("@buoy-gg/shared-ui");
|
|
10
|
-
var _jsxRuntime = require("react/jsx-runtime");
|
|
11
|
-
/**
|
|
12
|
-
* Pre-configured Jotai DevTools preset for FloatingDevTools
|
|
13
|
-
*
|
|
14
|
-
* ZERO-CONFIG: This preset is auto-discovered by FloatingDevTools!
|
|
15
|
-
* Just install @buoy-gg/jotai and call watchAtoms() with your atoms.
|
|
16
|
-
*
|
|
17
|
-
* @example Automatic (recommended)
|
|
18
|
-
* ```tsx
|
|
19
|
-
* import { getDefaultStore } from 'jotai';
|
|
20
|
-
* import { watchAtoms } from '@buoy-gg/jotai';
|
|
21
|
-
* import { countAtom, authAtom } from './atoms';
|
|
22
|
-
*
|
|
23
|
-
* watchAtoms(getDefaultStore(), { countAtom, authAtom });
|
|
24
|
-
*
|
|
25
|
-
* // The Jotai tool appears automatically in FloatingDevTools!
|
|
26
|
-
* <FloatingDevTools />
|
|
27
|
-
* ```
|
|
28
|
-
*
|
|
29
|
-
* @example Manual (only for custom configuration)
|
|
30
|
-
* ```tsx
|
|
31
|
-
* import { createJotaiTool } from '@buoy-gg/jotai';
|
|
32
|
-
*
|
|
33
|
-
* const customJotaiTool = createJotaiTool({
|
|
34
|
-
* name: "ATOMS",
|
|
35
|
-
* iconColor: "#6C47FF",
|
|
36
|
-
* });
|
|
37
|
-
*
|
|
38
|
-
* <FloatingDevTools apps={[customJotaiTool]} />
|
|
39
|
-
* ```
|
|
40
|
-
*/
|
|
41
|
-
|
|
42
|
-
/**
|
|
43
|
-
* Pre-configured Jotai DevTools preset for FloatingDevTools.
|
|
44
|
-
* Includes:
|
|
45
|
-
* - Live atom change monitoring
|
|
46
|
-
* - Atom value inspection (JSON viewer)
|
|
47
|
-
* - Value diff visualization (tree + split)
|
|
48
|
-
* - Filter by atom label
|
|
49
|
-
* - Changed keys tracking for object atoms
|
|
50
|
-
*/
|
|
51
|
-
const jotaiToolPreset = exports.jotaiToolPreset = (0, _sharedUi.defineToolPreset)({
|
|
52
|
-
id: "jotai",
|
|
53
|
-
name: "JOTAI",
|
|
54
|
-
description: "Jotai atom & state inspector",
|
|
55
|
-
slot: "both",
|
|
56
|
-
icon: ({
|
|
57
|
-
size
|
|
58
|
-
}) => /*#__PURE__*/(0, _jsxRuntime.jsx)(_JotaiIcon.JotaiIcon, {
|
|
59
|
-
size: size
|
|
60
|
-
}),
|
|
61
|
-
component: _JotaiModal.JotaiModal,
|
|
62
|
-
props: {
|
|
63
|
-
enableSharedModalDimensions: false
|
|
64
|
-
}
|
|
65
|
-
});
|
|
66
|
-
|
|
67
|
-
/**
|
|
68
|
-
* Create a custom Jotai DevTools configuration.
|
|
69
|
-
* Use this if you want to override default settings.
|
|
70
|
-
*
|
|
71
|
-
* @example
|
|
72
|
-
* ```tsx
|
|
73
|
-
* import { createJotaiTool } from '@buoy-gg/jotai';
|
|
74
|
-
*
|
|
75
|
-
* const myJotaiTool = createJotaiTool({
|
|
76
|
-
* name: "ATOMS",
|
|
77
|
-
* iconColor: "#6C47FF",
|
|
78
|
-
* });
|
|
79
|
-
* ```
|
|
80
|
-
*/
|
|
81
|
-
const createJotaiTool = exports.createJotaiTool = (0, _sharedUi.createToolFactory)(jotaiToolPreset, options => ({
|
|
82
|
-
enableSharedModalDimensions: options.enableSharedModalDimensions ?? false
|
|
83
|
-
}), options => ({
|
|
84
|
-
icon: ({
|
|
85
|
-
size
|
|
86
|
-
}) => /*#__PURE__*/(0, _jsxRuntime.jsx)(_JotaiIcon.JotaiIcon, {
|
|
87
|
-
size: size,
|
|
88
|
-
color: options.iconColor
|
|
89
|
-
})
|
|
90
|
-
}));
|
|
1
|
+
"use strict";Object.defineProperty(exports,"__esModule",{value:true});exports.jotaiToolPreset=exports.createJotaiTool=void 0;var _JotaiModal=require("./jotai/components/JotaiModal");var _JotaiIcon=require("./jotai/components/JotaiIcon");var _sharedUi=require("@buoy-gg/shared-ui");var _jsxRuntime=require("react/jsx-runtime");const jotaiToolPreset=exports.jotaiToolPreset=(0,_sharedUi.defineToolPreset)({id:"jotai",name:"JOTAI",description:"Jotai atom & state inspector",slot:"both",icon:({size:o})=>(0,_jsxRuntime.jsx)(_JotaiIcon.JotaiIcon,{size:o}),component:_JotaiModal.JotaiModal,props:{enableSharedModalDimensions:false}});const createJotaiTool=exports.createJotaiTool=(0,_sharedUi.createToolFactory)(jotaiToolPreset,o=>({enableSharedModalDimensions:o.enableSharedModalDimensions??false}),o=>({icon:({size:e})=>(0,_jsxRuntime.jsx)(_JotaiIcon.JotaiIcon,{size:e,color:o.iconColor})}));
|
package/lib/module/index.js
CHANGED
|
@@ -1,85 +1 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* @buoy-gg/jotai
|
|
5
|
-
*
|
|
6
|
-
* Jotai Atom DevTools for React Native
|
|
7
|
-
*
|
|
8
|
-
* PUBLIC API - Only these exports are supported for external use.
|
|
9
|
-
*
|
|
10
|
-
* @example Recommended setup (one line, pass your atoms)
|
|
11
|
-
* ```tsx
|
|
12
|
-
* import { getDefaultStore } from 'jotai';
|
|
13
|
-
* import { watchAtoms } from '@buoy-gg/jotai';
|
|
14
|
-
* import { countAtom } from './atoms/count';
|
|
15
|
-
* import { authAtom } from './atoms/auth';
|
|
16
|
-
*
|
|
17
|
-
* // One call, anywhere at module scope or in your root layout:
|
|
18
|
-
* watchAtoms(getDefaultStore(), {
|
|
19
|
-
* countAtom,
|
|
20
|
-
* authAtom,
|
|
21
|
-
* });
|
|
22
|
-
* ```
|
|
23
|
-
*
|
|
24
|
-
* @example With a custom store (Provider-based)
|
|
25
|
-
* ```tsx
|
|
26
|
-
* import { createStore } from 'jotai';
|
|
27
|
-
* import { watchAtoms } from '@buoy-gg/jotai';
|
|
28
|
-
*
|
|
29
|
-
* const myStore = createStore();
|
|
30
|
-
*
|
|
31
|
-
* watchAtoms(myStore, { countAtom, authAtom });
|
|
32
|
-
* ```
|
|
33
|
-
*/
|
|
34
|
-
|
|
35
|
-
// Side-effect: registers the Time Machine snapshot provider
|
|
36
|
-
import "./jotai/utils/snapshotProvider";
|
|
37
|
-
|
|
38
|
-
// =============================================================================
|
|
39
|
-
// PRESET (Primary entry point for FloatingDevTools)
|
|
40
|
-
// =============================================================================
|
|
41
|
-
export { jotaiToolPreset, createJotaiTool } from "./preset";
|
|
42
|
-
|
|
43
|
-
// =============================================================================
|
|
44
|
-
// WATCH ATOMS (Recommended — subscribe-only, non-intrusive)
|
|
45
|
-
// =============================================================================
|
|
46
|
-
export { watchAtoms } from "./jotai/utils/watchAtoms";
|
|
47
|
-
|
|
48
|
-
// =============================================================================
|
|
49
|
-
// CONVENIENCE (Default store shortcut)
|
|
50
|
-
// =============================================================================
|
|
51
|
-
export { watchDefaultStoreAtoms } from "./jotai/utils/watchAtoms";
|
|
52
|
-
|
|
53
|
-
// =============================================================================
|
|
54
|
-
// UTILITIES
|
|
55
|
-
// =============================================================================
|
|
56
|
-
export { isAtomWatched } from "./jotai/utils/watchAtoms";
|
|
57
|
-
// =============================================================================
|
|
58
|
-
// HOOKS (For consuming Jotai atom data)
|
|
59
|
-
// =============================================================================
|
|
60
|
-
export { useJotaiAtomChanges } from "./jotai/hooks/useJotaiAtomChanges";
|
|
61
|
-
// =============================================================================
|
|
62
|
-
// COMPONENTS (For custom UI implementations)
|
|
63
|
-
// =============================================================================
|
|
64
|
-
// `JotaiToolView` is the same tool rendered inline (header bar + body + footer)
|
|
65
|
-
// instead of inside a JsModal — for hosts that show tools in a panel.
|
|
66
|
-
export { JotaiModal, JotaiToolView } from "./jotai/components/JotaiModal";
|
|
67
|
-
export { JotaiAtomChangeItem } from "./jotai/components/JotaiAtomChangeItem";
|
|
68
|
-
export { JotaiAtomDetailContent, JotaiAtomDetailFooter } from "./jotai/components/JotaiAtomDetailContent";
|
|
69
|
-
export { JotaiAtomValueDetailContent } from "./jotai/components/JotaiAtomValueDetailContent";
|
|
70
|
-
export { JotaiIcon, JOTAI_ICON_COLOR } from "./jotai/components/JotaiIcon";
|
|
71
|
-
|
|
72
|
-
// =============================================================================
|
|
73
|
-
// EXTERNAL SYNC (Adapter for @buoy-gg/external-sync's useExternalSync)
|
|
74
|
-
// =============================================================================
|
|
75
|
-
export { jotaiSyncAdapter } from "./jotai/sync/jotaiSyncAdapter";
|
|
76
|
-
|
|
77
|
-
// =============================================================================
|
|
78
|
-
// TYPES
|
|
79
|
-
// =============================================================================
|
|
80
|
-
|
|
81
|
-
// =============================================================================
|
|
82
|
-
// INTERNAL EXPORTS (For @buoy-gg/* packages only - not part of public API)
|
|
83
|
-
// =============================================================================
|
|
84
|
-
/** @internal */
|
|
85
|
-
export { jotaiStateStore } from "./jotai/utils/jotaiStateStore";
|
|
1
|
+
"use strict";import"./jotai/utils/snapshotProvider";export{jotaiToolPreset,createJotaiTool}from"./preset";export{watchAtoms}from"./jotai/utils/watchAtoms";export{watchDefaultStoreAtoms}from"./jotai/utils/watchAtoms";export{isAtomWatched}from"./jotai/utils/watchAtoms";export{useJotaiAtomChanges}from"./jotai/hooks/useJotaiAtomChanges";export{JotaiModal,JotaiToolView}from"./jotai/components/JotaiModal";export{JotaiAtomChangeItem}from"./jotai/components/JotaiAtomChangeItem";export{JotaiAtomDetailContent,JotaiAtomDetailFooter}from"./jotai/components/JotaiAtomDetailContent";export{JotaiAtomValueDetailContent}from"./jotai/components/JotaiAtomValueDetailContent";export{JotaiIcon,JOTAI_ICON_COLOR}from"./jotai/components/JotaiIcon";export{jotaiSyncAdapter}from"./jotai/sync/jotaiSyncAdapter";export{jotaiStateStore}from"./jotai/utils/jotaiStateStore";
|
|
@@ -1,195 +1 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* JotaiAtomBrowser
|
|
5
|
-
*
|
|
6
|
-
* Atoms tab — shows all registered Jotai atoms and their current value.
|
|
7
|
-
* Mirrors ZustandStoreBrowser.tsx from @buoy-gg/zustand: tapping a card
|
|
8
|
-
* NAVIGATES to the atom's detail screen (live editor + details + read-only
|
|
9
|
-
* tree) rather than expanding in place — the modal owns that selection.
|
|
10
|
-
*/
|
|
11
|
-
|
|
12
|
-
import { useMemo } from "react";
|
|
13
|
-
import { View, Text, StyleSheet, ScrollView } from "react-native";
|
|
14
|
-
import { CompactRow, night, ToolEmptyState, resolveListEmptyState, monoFont } from "@buoy-gg/shared-ui";
|
|
15
|
-
import { jotaiStateStore } from "../utils/jotaiStateStore";
|
|
16
|
-
import { JOTAI_TEST_ID, atomRowTestID } from "../utils/testIDs";
|
|
17
|
-
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
18
|
-
function getValuePreview(atom) {
|
|
19
|
-
try {
|
|
20
|
-
const value = atom.getValue();
|
|
21
|
-
if (value && typeof value === "object" && value.__buoyValueOnDevice === true) {
|
|
22
|
-
return "on device";
|
|
23
|
-
}
|
|
24
|
-
if (value === undefined) return "undefined";
|
|
25
|
-
if (value === null) return "null";
|
|
26
|
-
if (Array.isArray(value)) {
|
|
27
|
-
if (value.length === 0) return "[]";
|
|
28
|
-
return `[${value.length} item${value.length === 1 ? "" : "s"}]`;
|
|
29
|
-
}
|
|
30
|
-
if (typeof value === "object") {
|
|
31
|
-
const keys = Object.keys(value);
|
|
32
|
-
if (keys.length === 0) return "{}";
|
|
33
|
-
if (keys.length <= 3) return keys.join(", ");
|
|
34
|
-
return `${keys.slice(0, 2).join(", ")} +${keys.length - 2}`;
|
|
35
|
-
}
|
|
36
|
-
return String(value).slice(0, 40);
|
|
37
|
-
} catch {
|
|
38
|
-
return "";
|
|
39
|
-
}
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
/**
|
|
43
|
-
* The card's categorical slot — the atom's write story, mirroring the
|
|
44
|
-
* zustand card's "persisted"/"in-memory" backing label.
|
|
45
|
-
*/
|
|
46
|
-
function getWriteKindLabel(atom) {
|
|
47
|
-
if (atom.writeKind === "value") return "primitive";
|
|
48
|
-
if (atom.writeKind === "action") return "custom write";
|
|
49
|
-
return atom.setValue ? "writable" : "derived";
|
|
50
|
-
}
|
|
51
|
-
function EmptyBrowserState() {
|
|
52
|
-
return /*#__PURE__*/_jsx(ToolEmptyState, {
|
|
53
|
-
testID: `${JOTAI_TEST_ID}-atoms-empty`
|
|
54
|
-
// scanning = "scanning for targets… and finding none". The registry is
|
|
55
|
-
// discovered, not configured, so an empty one is a scan result.
|
|
56
|
-
,
|
|
57
|
-
otto: "scanning",
|
|
58
|
-
title: "No atoms registered",
|
|
59
|
-
message: "Use watchAtoms(store, { atomName }) to register your Jotai atoms.\nThey will appear here with their current value."
|
|
60
|
-
});
|
|
61
|
-
}
|
|
62
|
-
export function JotaiAtomBrowser({
|
|
63
|
-
atoms,
|
|
64
|
-
searchQuery,
|
|
65
|
-
onOpenAtom
|
|
66
|
-
}) {
|
|
67
|
-
const filteredAtoms = useMemo(() => {
|
|
68
|
-
if (!searchQuery) return atoms;
|
|
69
|
-
const search = searchQuery.toLowerCase();
|
|
70
|
-
return atoms.filter(a => a.label.toLowerCase().includes(search));
|
|
71
|
-
}, [atoms, searchQuery]);
|
|
72
|
-
if (filteredAtoms.length === 0 && !searchQuery) {
|
|
73
|
-
return /*#__PURE__*/_jsx(EmptyBrowserState, {});
|
|
74
|
-
}
|
|
75
|
-
if (filteredAtoms.length === 0 && searchQuery) {
|
|
76
|
-
return /*#__PURE__*/_jsx(ToolEmptyState, {
|
|
77
|
-
testID: `${JOTAI_TEST_ID}-atoms-no-match`,
|
|
78
|
-
...resolveListEmptyState({
|
|
79
|
-
subject: "atoms",
|
|
80
|
-
verb: "registered",
|
|
81
|
-
search: searchQuery,
|
|
82
|
-
total: atoms.length,
|
|
83
|
-
waiting: {
|
|
84
|
-
otto: "scanning",
|
|
85
|
-
title: "No atoms registered",
|
|
86
|
-
message: "Use watchAtoms() to register your Jotai atoms."
|
|
87
|
-
}
|
|
88
|
-
})
|
|
89
|
-
});
|
|
90
|
-
}
|
|
91
|
-
return /*#__PURE__*/_jsxs(ScrollView, {
|
|
92
|
-
style: styles.container,
|
|
93
|
-
contentContainerStyle: styles.scrollContent,
|
|
94
|
-
showsVerticalScrollIndicator: true,
|
|
95
|
-
testID: `${JOTAI_TEST_ID}-atoms-scroll`,
|
|
96
|
-
children: [/*#__PURE__*/_jsxs(View, {
|
|
97
|
-
style: styles.sectionHeader,
|
|
98
|
-
children: [/*#__PURE__*/_jsx(Text, {
|
|
99
|
-
style: styles.sectionTitle,
|
|
100
|
-
children: "ATOMS"
|
|
101
|
-
}), /*#__PURE__*/_jsx(View, {
|
|
102
|
-
style: styles.sectionCountBadge,
|
|
103
|
-
children: /*#__PURE__*/_jsx(Text, {
|
|
104
|
-
style: styles.sectionCountText,
|
|
105
|
-
testID: `${JOTAI_TEST_ID}-atoms-count`,
|
|
106
|
-
children: filteredAtoms.length
|
|
107
|
-
})
|
|
108
|
-
})]
|
|
109
|
-
}), filteredAtoms.map(atom => {
|
|
110
|
-
const valuePreview = getValuePreview(atom);
|
|
111
|
-
const atomColor = jotaiStateStore.getAtomColor(atom.label);
|
|
112
|
-
const rowID = atomRowTestID(atom.label);
|
|
113
|
-
return /*#__PURE__*/_jsxs(View, {
|
|
114
|
-
style: styles.atomRowWrapper,
|
|
115
|
-
children: [/*#__PURE__*/_jsx(CompactRow, {
|
|
116
|
-
statusDotColor: atomColor,
|
|
117
|
-
statusLabel: getWriteKindLabel(atom),
|
|
118
|
-
primaryText: atom.label,
|
|
119
|
-
secondaryText: valuePreview || undefined,
|
|
120
|
-
showChevron: true,
|
|
121
|
-
onPress: () => onOpenAtom(atom.label),
|
|
122
|
-
testID: rowID,
|
|
123
|
-
statusTestID: `${rowID}-kind`,
|
|
124
|
-
primaryTestID: `${rowID}-name`,
|
|
125
|
-
secondaryTestID: `${rowID}-preview`
|
|
126
|
-
}), atom.changeCount > 0 && /*#__PURE__*/_jsx(View, {
|
|
127
|
-
style: [styles.absCountBadge, {
|
|
128
|
-
backgroundColor: atomColor + "22",
|
|
129
|
-
borderColor: atomColor + "55"
|
|
130
|
-
}],
|
|
131
|
-
pointerEvents: "none",
|
|
132
|
-
children: /*#__PURE__*/_jsx(Text, {
|
|
133
|
-
style: [styles.absCountText, {
|
|
134
|
-
color: atomColor
|
|
135
|
-
}],
|
|
136
|
-
testID: `${rowID}-count`,
|
|
137
|
-
children: String(atom.changeCount)
|
|
138
|
-
})
|
|
139
|
-
})]
|
|
140
|
-
}, atom.label);
|
|
141
|
-
})]
|
|
142
|
-
});
|
|
143
|
-
}
|
|
144
|
-
const styles = StyleSheet.create({
|
|
145
|
-
container: {
|
|
146
|
-
flex: 1
|
|
147
|
-
},
|
|
148
|
-
atomRowWrapper: {
|
|
149
|
-
position: "relative"
|
|
150
|
-
},
|
|
151
|
-
absCountBadge: {
|
|
152
|
-
position: "absolute",
|
|
153
|
-
top: 4,
|
|
154
|
-
right: 10,
|
|
155
|
-
paddingHorizontal: 5,
|
|
156
|
-
paddingVertical: 1,
|
|
157
|
-
borderRadius: 4,
|
|
158
|
-
borderWidth: 1,
|
|
159
|
-
zIndex: 1
|
|
160
|
-
},
|
|
161
|
-
absCountText: {
|
|
162
|
-
fontSize: 9,
|
|
163
|
-
fontWeight: "700",
|
|
164
|
-
fontFamily: monoFont
|
|
165
|
-
},
|
|
166
|
-
scrollContent: {
|
|
167
|
-
paddingTop: 8,
|
|
168
|
-
paddingBottom: 20
|
|
169
|
-
},
|
|
170
|
-
sectionHeader: {
|
|
171
|
-
flexDirection: "row",
|
|
172
|
-
alignItems: "center",
|
|
173
|
-
paddingHorizontal: 16,
|
|
174
|
-
paddingVertical: 8,
|
|
175
|
-
gap: 8
|
|
176
|
-
},
|
|
177
|
-
sectionTitle: {
|
|
178
|
-
fontSize: 11,
|
|
179
|
-
fontWeight: "700",
|
|
180
|
-
letterSpacing: 0.5,
|
|
181
|
-
color: night.color.textTertiary
|
|
182
|
-
},
|
|
183
|
-
sectionCountBadge: {
|
|
184
|
-
backgroundColor: night.color.accentFill,
|
|
185
|
-
paddingHorizontal: 8,
|
|
186
|
-
paddingVertical: 2,
|
|
187
|
-
borderRadius: 4
|
|
188
|
-
},
|
|
189
|
-
sectionCountText: {
|
|
190
|
-
fontSize: 10,
|
|
191
|
-
fontWeight: "700",
|
|
192
|
-
color: night.color.accent,
|
|
193
|
-
fontFamily: monoFont
|
|
194
|
-
}
|
|
195
|
-
});
|
|
1
|
+
"use strict";import{useMemo as y}from"react";import{View as c,Text as g,StyleSheet as b,ScrollView as w}from"react-native";import{CompactRow as C,night as f,ToolEmptyState as p,resolveListEmptyState as T,monoFont as h}from"@buoy-gg/shared-ui";import{jotaiStateStore as S}from"../utils/jotaiStateStore";import{JOTAI_TEST_ID as u,atomRowTestID as v}from"../utils/testIDs";import{jsx as r,jsxs as m}from"react/jsx-runtime";function x(o){try{const t=o.getValue();if(t&&typeof t==="object"&&t.__buoyValueOnDevice===true){return"on device"}if(t===void 0)return"undefined";if(t===null)return"null";if(Array.isArray(t)){if(t.length===0)return"[]";return`[${t.length} item${t.length===1?"":"s"}]`}if(typeof t==="object"){const i=Object.keys(t);if(i.length===0)return"{}";if(i.length<=3)return i.join(", ");return`${i.slice(0,2).join(", ")} +${i.length-2}`}return String(t).slice(0,40)}catch{return""}}function I(o){if(o.writeKind==="value")return"primitive";if(o.writeKind==="action")return"custom write";return o.setValue?"writable":"derived"}function D(){return r(p,{testID:`${u}-atoms-empty`,otto:"scanning",title:"No atoms registered",message:"Use watchAtoms(store, { atomName }) to register your Jotai atoms.\nThey will appear here with their current value."})}export function JotaiAtomBrowser({atoms:o,searchQuery:t,onOpenAtom:i}){const l=y(()=>{if(!t)return o;const e=t.toLowerCase();return o.filter(d=>d.label.toLowerCase().includes(e))},[o,t]);if(l.length===0&&!t){return r(D,{})}if(l.length===0&&t){return r(p,{testID:`${u}-atoms-no-match`,...T({subject:"atoms",verb:"registered",search:t,total:o.length,waiting:{otto:"scanning",title:"No atoms registered",message:"Use watchAtoms() to register your Jotai atoms."}})})}return m(w,{style:n.container,contentContainerStyle:n.scrollContent,showsVerticalScrollIndicator:true,testID:`${u}-atoms-scroll`,children:[m(c,{style:n.sectionHeader,children:[r(g,{style:n.sectionTitle,children:"ATOMS"}),r(c,{style:n.sectionCountBadge,children:r(g,{style:n.sectionCountText,testID:`${u}-atoms-count`,children:l.length})})]}),l.map(e=>{const d=x(e);const a=S.getAtomColor(e.label);const s=v(e.label);return m(c,{style:n.atomRowWrapper,children:[r(C,{statusDotColor:a,statusLabel:I(e),primaryText:e.label,secondaryText:d||void 0,showChevron:true,onPress:()=>i(e.label),testID:s,statusTestID:`${s}-kind`,primaryTestID:`${s}-name`,secondaryTestID:`${s}-preview`}),e.changeCount>0&&r(c,{style:[n.absCountBadge,{backgroundColor:a+"22",borderColor:a+"55"}],pointerEvents:"none",children:r(g,{style:[n.absCountText,{color:a}],testID:`${s}-count`,children:String(e.changeCount)})})]},e.label)})]})}const n=b.create({container:{flex:1},atomRowWrapper:{position:"relative"},absCountBadge:{position:"absolute",top:4,right:10,paddingHorizontal:5,paddingVertical:1,borderRadius:4,borderWidth:1,zIndex:1},absCountText:{fontSize:9,fontWeight:"700",fontFamily:h},scrollContent:{paddingTop:8,paddingBottom:20},sectionHeader:{flexDirection:"row",alignItems:"center",paddingHorizontal:16,paddingVertical:8,gap:8},sectionTitle:{fontSize:11,fontWeight:"700",letterSpacing:.5,color:f.color.textTertiary},sectionCountBadge:{backgroundColor:f.color.accentFill,paddingHorizontal:8,paddingVertical:2,borderRadius:4},sectionCountText:{fontSize:10,fontWeight:"700",color:f.color.accent,fontFamily:h}});
|
|
@@ -1,91 +1 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Compact list item for displaying a Jotai atom change
|
|
5
|
-
*
|
|
6
|
-
* Mirrors ZustandStateChangeItem.tsx — uses shared CompactRow for consistent styling
|
|
7
|
-
*/
|
|
8
|
-
|
|
9
|
-
import { memo } from "react";
|
|
10
|
-
import { ChangeRow, night } from "@buoy-gg/shared-ui";
|
|
11
|
-
import { jotaiStateStore } from "../utils/jotaiStateStore";
|
|
12
|
-
import { jsx as _jsx } from "react/jsx-runtime";
|
|
13
|
-
/**
|
|
14
|
-
* The atom's name, exactly as registered. INIT rows used to read "Initial",
|
|
15
|
-
* so five registrations were five identical rows, and the name was
|
|
16
|
-
* capitalized ("VisibleCountAtom") into something the code doesn't contain.
|
|
17
|
-
* The INIT badge already says what kind of event it is.
|
|
18
|
-
*/
|
|
19
|
-
function getStatusLabel(_category, atomLabel) {
|
|
20
|
-
return atomLabel;
|
|
21
|
-
}
|
|
22
|
-
function getCategoryColor(category, atomLabel) {
|
|
23
|
-
if (category === "initial") return night.color.textTertiary;
|
|
24
|
-
return jotaiStateStore.getAtomColor(atomLabel);
|
|
25
|
-
}
|
|
26
|
-
function formatCompact(value, maxLen = 20) {
|
|
27
|
-
if (value === undefined) return "undefined";
|
|
28
|
-
if (value === null) return "null";
|
|
29
|
-
if (typeof value === "boolean") return String(value);
|
|
30
|
-
if (typeof value === "number") return String(value);
|
|
31
|
-
if (typeof value === "string") {
|
|
32
|
-
const truncated = value.length > maxLen ? value.slice(0, maxLen - 1) + "…" : value;
|
|
33
|
-
return `"${truncated}"`;
|
|
34
|
-
}
|
|
35
|
-
if (Array.isArray(value)) {
|
|
36
|
-
return value.length === 0 ? "[]" : `[${value.length} item${value.length === 1 ? "" : "s"}]`;
|
|
37
|
-
}
|
|
38
|
-
if (typeof value === "object") {
|
|
39
|
-
const keys = Object.keys(value);
|
|
40
|
-
if (keys.length === 0) return "{}";
|
|
41
|
-
return `{${keys.slice(0, 2).join(", ")}${keys.length > 2 ? "…" : ""}}`;
|
|
42
|
-
}
|
|
43
|
-
return String(value).slice(0, maxLen);
|
|
44
|
-
}
|
|
45
|
-
function getSublabel(change) {
|
|
46
|
-
if (!change.hasValueChange) return "no change";
|
|
47
|
-
return `${formatCompact(change.prevValue)} → ${formatCompact(change.nextValue)}`;
|
|
48
|
-
}
|
|
49
|
-
function getBadgeText(change) {
|
|
50
|
-
if (change.category === "initial") return "INIT";
|
|
51
|
-
return "WRITE";
|
|
52
|
-
}
|
|
53
|
-
function getPrimaryText(change) {
|
|
54
|
-
// Changed keys only mean something for a plain object. For an array they
|
|
55
|
-
// are indices ("15, 16 +18"), so show the new value instead.
|
|
56
|
-
const next = change.nextValue;
|
|
57
|
-
const isPlainObject = typeof next === "object" && next !== null && !Array.isArray(next);
|
|
58
|
-
if (!isPlainObject) return formatCompact(next);
|
|
59
|
-
if (change.changedKeys.length > 0 && change.changedKeys.length <= 3) {
|
|
60
|
-
return change.changedKeys.join(", ");
|
|
61
|
-
}
|
|
62
|
-
if (change.changedKeys.length > 3) {
|
|
63
|
-
return `${change.changedKeys.slice(0, 2).join(", ")} +${change.changedKeys.length - 2}`;
|
|
64
|
-
}
|
|
65
|
-
return change.valuePreview || "atom()";
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
// Memo justified by profiling (tool-bench 2026-07-06) — see
|
|
69
|
-
// ZustandStateChangeItem (same pattern).
|
|
70
|
-
export const JotaiAtomChangeItem = /*#__PURE__*/memo(function JotaiAtomChangeItem({
|
|
71
|
-
change,
|
|
72
|
-
onPress,
|
|
73
|
-
testID
|
|
74
|
-
}) {
|
|
75
|
-
const statusColor = getCategoryColor(change.category, change.atomLabel);
|
|
76
|
-
const statusLabel = getStatusLabel(change.category, change.atomLabel);
|
|
77
|
-
const sublabel = getSublabel(change);
|
|
78
|
-
const primaryText = getPrimaryText(change);
|
|
79
|
-
const badgeText = getBadgeText(change);
|
|
80
|
-
return /*#__PURE__*/_jsx(ChangeRow, {
|
|
81
|
-
statusColor: statusColor,
|
|
82
|
-
statusLabel: statusLabel,
|
|
83
|
-
sublabel: sublabel,
|
|
84
|
-
primaryText: primaryText,
|
|
85
|
-
timestamp: change.timestamp,
|
|
86
|
-
badgeText: badgeText,
|
|
87
|
-
changed: change.hasValueChange,
|
|
88
|
-
onPress: () => onPress(change),
|
|
89
|
-
testID: testID
|
|
90
|
-
});
|
|
91
|
-
});
|
|
1
|
+
"use strict";import{memo as l}from"react";import{ChangeRow as m,night as y}from"@buoy-gg/shared-ui";import{jotaiStateStore as g}from"../utils/jotaiStateStore";import{jsx as c}from"react/jsx-runtime";function b(t,e){return e}function p(t,e){if(t==="initial")return y.color.textTertiary;return g.getAtomColor(e)}function n(t,e=20){if(t===void 0)return"undefined";if(t===null)return"null";if(typeof t==="boolean")return String(t);if(typeof t==="number")return String(t);if(typeof t==="string"){const r=t.length>e?t.slice(0,e-1)+"\u2026":t;return`"${r}"`}if(Array.isArray(t)){return t.length===0?"[]":`[${t.length} item${t.length===1?"":"s"}]`}if(typeof t==="object"){const r=Object.keys(t);if(r.length===0)return"{}";return`{${r.slice(0,2).join(", ")}${r.length>2?"\u2026":""}}`}return String(t).slice(0,e)}function d(t){if(!t.hasValueChange)return"no change";return`${n(t.prevValue)} \u2192 ${n(t.nextValue)}`}function x(t){if(t.category==="initial")return"INIT";return"WRITE"}function C(t){const e=t.nextValue;const r=typeof e==="object"&&e!==null&&!Array.isArray(e);if(!r)return n(e);if(t.changedKeys.length>0&&t.changedKeys.length<=3){return t.changedKeys.join(", ")}if(t.changedKeys.length>3){return`${t.changedKeys.slice(0,2).join(", ")} +${t.changedKeys.length-2}`}return t.valuePreview||"atom()"}export const JotaiAtomChangeItem=l(function t({change:e,onPress:r,testID:o}){const i=p(e.category,e.atomLabel);const s=b(e.category,e.atomLabel);const u=d(e);const f=C(e);const a=x(e);return c(m,{statusColor:i,statusLabel:s,sublabel:u,primaryText:f,timestamp:e.timestamp,badgeText:a,changed:e.hasValueChange,onPress:()=>r(e),testID:o})});
|