@treenity/react 3.0.1 → 3.0.3
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 +1 -1
- package/dist/App.d.ts.map +1 -1
- package/dist/App.js +33 -7
- package/dist/App.js.map +1 -1
- package/dist/ComponentSection.js +1 -1
- package/dist/ComponentSection.js.map +1 -1
- package/dist/ErrorBoundary.d.ts.map +1 -1
- package/dist/ErrorBoundary.js +2 -1
- package/dist/ErrorBoundary.js.map +1 -1
- package/dist/Treenity.d.ts +15 -0
- package/dist/Treenity.d.ts.map +1 -0
- package/dist/Treenity.js +17 -0
- package/dist/Treenity.js.map +1 -0
- package/dist/cache.d.ts.map +1 -1
- package/dist/cache.js +5 -0
- package/dist/cache.js.map +1 -1
- package/dist/client-tree.d.ts.map +1 -1
- package/dist/client-tree.js +2 -2
- package/dist/client-tree.js.map +1 -1
- package/dist/components/ui/button.d.ts +2 -2
- package/dist/components/ui/button.d.ts.map +1 -1
- package/dist/components/ui/button.js +3 -3
- package/dist/components/ui/button.js.map +1 -1
- package/dist/components/ui/pagination.d.ts +2 -2
- package/dist/components/ui/pagination.d.ts.map +1 -1
- package/dist/components/ui/pagination.js +3 -3
- package/dist/components/ui/pagination.js.map +1 -1
- package/dist/components/ui/textarea.js +1 -1
- package/dist/components/ui/textarea.js.map +1 -1
- package/dist/events.d.ts +2 -0
- package/dist/events.d.ts.map +1 -1
- package/dist/events.js +47 -2
- package/dist/events.js.map +1 -1
- package/dist/fiber-tree.d.ts.map +1 -1
- package/dist/fiber-tree.js.map +1 -1
- package/dist/hooks.d.ts +9 -0
- package/dist/hooks.d.ts.map +1 -1
- package/dist/hooks.js +80 -5
- package/dist/hooks.js.map +1 -1
- package/dist/lib/minimd.d.ts.map +1 -1
- package/dist/lib/minimd.js +8 -1
- package/dist/lib/minimd.js.map +1 -1
- package/dist/lib/sanitize-href.d.ts +3 -0
- package/dist/lib/sanitize-href.d.ts.map +1 -0
- package/dist/lib/sanitize-href.js +14 -0
- package/dist/lib/sanitize-href.js.map +1 -0
- package/dist/main.d.ts +2 -0
- package/dist/main.d.ts.map +1 -1
- package/dist/main.js +14 -5
- package/dist/main.js.map +1 -1
- package/dist/mods/editor-ui/FieldLabel.d.ts.map +1 -1
- package/dist/mods/editor-ui/FieldLabel.js +2 -1
- package/dist/mods/editor-ui/FieldLabel.js.map +1 -1
- package/dist/mods/editor-ui/default-edit.js +4 -2
- package/dist/mods/editor-ui/default-edit.js.map +1 -1
- package/dist/mods/editor-ui/form-field.d.ts.map +1 -1
- package/dist/mods/editor-ui/form-field.js +3 -2
- package/dist/mods/editor-ui/form-field.js.map +1 -1
- package/dist/mods/editor-ui/type-picker.d.ts.map +1 -1
- package/dist/mods/editor-ui/type-picker.js +2 -1
- package/dist/mods/editor-ui/type-picker.js.map +1 -1
- package/dist/mods/treenity/preview.d.ts.map +1 -1
- package/dist/mods/treenity/preview.js +2 -3
- package/dist/mods/treenity/preview.js.map +1 -1
- package/dist/mods/treenity/ref-view.js +2 -1
- package/dist/mods/treenity/ref-view.js.map +1 -1
- package/dist/mods/treenity/seed.js +3 -2
- package/dist/mods/treenity/seed.js.map +1 -1
- package/dist/symbols.d.ts.map +1 -1
- package/dist/symbols.js +11 -5
- package/dist/symbols.js.map +1 -1
- package/package.json +4 -2
- package/src/App.tsx +29 -1
- package/src/ComponentSection.tsx +1 -1
- package/src/ErrorBoundary.tsx +6 -3
- package/src/Treenity.tsx +32 -0
- package/src/cache.ts +7 -0
- package/src/client-tree.ts +7 -7
- package/src/components/ui/button.tsx +4 -5
- package/src/components/ui/pagination.tsx +4 -9
- package/src/components/ui/textarea.tsx +1 -1
- package/src/events.ts +46 -6
- package/src/fiber-tree.ts +3 -3
- package/src/hooks.ts +73 -4
- package/src/lib/minimd.ts +7 -1
- package/src/lib/sanitize-href.ts +13 -0
- package/src/main.tsx +23 -11
- package/src/mods/editor-ui/FieldLabel.tsx +5 -4
- package/src/mods/editor-ui/default-edit.tsx +6 -4
- package/src/mods/editor-ui/form-field.tsx +4 -2
- package/src/mods/editor-ui/type-picker.tsx +3 -2
- package/src/mods/treenity/preview.tsx +6 -7
- package/src/mods/treenity/ref-view.tsx +11 -6
- package/src/mods/treenity/seed.ts +3 -2
- package/src/symbols.ts +12 -5
- package/src/bind/bind.test.ts +0 -316
- package/src/cache.test.ts +0 -139
- package/src/client-tree.test.ts +0 -116
- package/src/optimistic.test.ts +0 -111
- package/src/remote-tree.test.ts +0 -142
package/src/remote-tree.test.ts
DELETED
|
@@ -1,142 +0,0 @@
|
|
|
1
|
-
import type { NodeData } from '@treenity/core';
|
|
2
|
-
import { withCache } from '@treenity/core/tree/cache';
|
|
3
|
-
import assert from 'node:assert/strict';
|
|
4
|
-
import { describe, it } from 'node:test';
|
|
5
|
-
import { createRemoteTree } from './remote-tree';
|
|
6
|
-
|
|
7
|
-
// ── Mock tRPC client ──
|
|
8
|
-
|
|
9
|
-
function createMockTrpc(backing: Map<string, NodeData>) {
|
|
10
|
-
let getCalls = 0;
|
|
11
|
-
|
|
12
|
-
const mock = {
|
|
13
|
-
get getCalls() { return getCalls; },
|
|
14
|
-
resetCalls() { getCalls = 0; },
|
|
15
|
-
|
|
16
|
-
get: {
|
|
17
|
-
query: async ({ path }: { path: string }) => {
|
|
18
|
-
getCalls++;
|
|
19
|
-
return backing.get(path);
|
|
20
|
-
},
|
|
21
|
-
},
|
|
22
|
-
getChildren: {
|
|
23
|
-
query: async ({ path, limit, offset }: { path: string; limit?: number; offset?: number }) => {
|
|
24
|
-
getCalls++;
|
|
25
|
-
const prefix = path === '/' ? '/' : path + '/';
|
|
26
|
-
const items = [...backing.values()].filter(
|
|
27
|
-
n => n.$path.startsWith(prefix) && n.$path !== path
|
|
28
|
-
&& n.$path.slice(prefix.length).indexOf('/') === -1,
|
|
29
|
-
);
|
|
30
|
-
const start = offset ?? 0;
|
|
31
|
-
const sliced = limit ? items.slice(start, start + limit) : items.slice(start);
|
|
32
|
-
return { items: sliced, total: items.length };
|
|
33
|
-
},
|
|
34
|
-
},
|
|
35
|
-
set: {
|
|
36
|
-
mutate: async ({ node }: { node: Record<string, unknown> }) => {
|
|
37
|
-
backing.set(node.$path as string, node as NodeData);
|
|
38
|
-
},
|
|
39
|
-
},
|
|
40
|
-
remove: {
|
|
41
|
-
mutate: async ({ path }: { path: string }) => {
|
|
42
|
-
backing.delete(path);
|
|
43
|
-
},
|
|
44
|
-
},
|
|
45
|
-
};
|
|
46
|
-
|
|
47
|
-
return mock;
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
// ── Tests ──
|
|
51
|
-
|
|
52
|
-
describe('createRemoteTree — method mapping', () => {
|
|
53
|
-
it('get delegates to trpc.get.query', async () => {
|
|
54
|
-
const data = new Map<string, NodeData>();
|
|
55
|
-
data.set('/a', { $path: '/a', $type: 'test', v: 1 } as NodeData);
|
|
56
|
-
const mock = createMockTrpc(data);
|
|
57
|
-
const store = createRemoteTree(mock as any);
|
|
58
|
-
|
|
59
|
-
const node = await store.get('/a');
|
|
60
|
-
assert.equal(node?.$path, '/a');
|
|
61
|
-
assert.equal((node as any).v, 1);
|
|
62
|
-
assert.equal(mock.getCalls, 1);
|
|
63
|
-
});
|
|
64
|
-
|
|
65
|
-
it('get returns undefined for missing path', async () => {
|
|
66
|
-
const store = createRemoteTree(createMockTrpc(new Map()) as any);
|
|
67
|
-
const node = await store.get('/missing');
|
|
68
|
-
assert.equal(node, undefined);
|
|
69
|
-
});
|
|
70
|
-
|
|
71
|
-
it('getChildren delegates to trpc.getChildren.query', async () => {
|
|
72
|
-
const data = new Map<string, NodeData>();
|
|
73
|
-
data.set('/p', { $path: '/p', $type: 'dir' } as NodeData);
|
|
74
|
-
data.set('/p/a', { $path: '/p/a', $type: 'test' } as NodeData);
|
|
75
|
-
data.set('/p/b', { $path: '/p/b', $type: 'test' } as NodeData);
|
|
76
|
-
const store = createRemoteTree(createMockTrpc(data) as any);
|
|
77
|
-
|
|
78
|
-
const result = await store.getChildren('/p');
|
|
79
|
-
assert.equal(result.items.length, 2);
|
|
80
|
-
assert.equal(result.total, 2);
|
|
81
|
-
});
|
|
82
|
-
|
|
83
|
-
it('set delegates to trpc.set.mutate', async () => {
|
|
84
|
-
const data = new Map<string, NodeData>();
|
|
85
|
-
const store = createRemoteTree(createMockTrpc(data) as any);
|
|
86
|
-
|
|
87
|
-
await store.set({ $path: '/x', $type: 'test', v: 42 } as NodeData);
|
|
88
|
-
assert.ok(data.has('/x'));
|
|
89
|
-
assert.equal((data.get('/x') as any).v, 42);
|
|
90
|
-
});
|
|
91
|
-
|
|
92
|
-
it('remove delegates to trpc.remove.mutate', async () => {
|
|
93
|
-
const data = new Map<string, NodeData>();
|
|
94
|
-
data.set('/x', { $path: '/x', $type: 'test' } as NodeData);
|
|
95
|
-
const store = createRemoteTree(createMockTrpc(data) as any);
|
|
96
|
-
|
|
97
|
-
const result = await store.remove('/x');
|
|
98
|
-
assert.equal(result, true);
|
|
99
|
-
assert.ok(!data.has('/x'));
|
|
100
|
-
});
|
|
101
|
-
});
|
|
102
|
-
|
|
103
|
-
describe('withCache(remoteStore) — client pipeline', () => {
|
|
104
|
-
it('caches get results — second call skips tRPC', async () => {
|
|
105
|
-
const data = new Map<string, NodeData>();
|
|
106
|
-
data.set('/a', { $path: '/a', $type: 'test' } as NodeData);
|
|
107
|
-
const mock = createMockTrpc(data);
|
|
108
|
-
const store = withCache(createRemoteTree(mock as any));
|
|
109
|
-
|
|
110
|
-
await store.get('/a');
|
|
111
|
-
mock.resetCalls();
|
|
112
|
-
await store.get('/a'); // should hit cache
|
|
113
|
-
assert.equal(mock.getCalls, 0);
|
|
114
|
-
});
|
|
115
|
-
|
|
116
|
-
it('write-populate: set warms cache for next get', async () => {
|
|
117
|
-
const data = new Map<string, NodeData>();
|
|
118
|
-
const mock = createMockTrpc(data);
|
|
119
|
-
const store = withCache(createRemoteTree(mock as any));
|
|
120
|
-
|
|
121
|
-
await store.set({ $path: '/a', $type: 'test', v: 1 } as NodeData);
|
|
122
|
-
mock.resetCalls();
|
|
123
|
-
|
|
124
|
-
const node = await store.get('/a'); // should hit cache (write-populated)
|
|
125
|
-
assert.equal(mock.getCalls, 0);
|
|
126
|
-
assert.equal((node as any).v, 1);
|
|
127
|
-
});
|
|
128
|
-
|
|
129
|
-
it('inflight dedup: concurrent gets produce single tRPC call', async () => {
|
|
130
|
-
const data = new Map<string, NodeData>();
|
|
131
|
-
data.set('/a', { $path: '/a', $type: 'test', v: 99 } as NodeData);
|
|
132
|
-
const mock = createMockTrpc(data);
|
|
133
|
-
const store = withCache(createRemoteTree(mock as any));
|
|
134
|
-
|
|
135
|
-
const results = await Promise.all(
|
|
136
|
-
Array.from({ length: 5 }, () => store.get('/a')),
|
|
137
|
-
);
|
|
138
|
-
|
|
139
|
-
assert.equal(mock.getCalls, 1);
|
|
140
|
-
for (const r of results) assert.equal((r as any).v, 99);
|
|
141
|
-
});
|
|
142
|
-
});
|