@treenity/react 3.0.0 → 3.0.2
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 +91 -0
- package/dist/AclEditor.d.ts +1 -1
- package/dist/AclEditor.d.ts.map +1 -1
- package/dist/AclEditor.js +5 -5
- package/dist/AclEditor.js.map +1 -1
- package/dist/ActionCards.d.ts +9 -0
- package/dist/ActionCards.d.ts.map +1 -0
- package/dist/ActionCards.js +96 -0
- package/dist/ActionCards.js.map +1 -0
- package/dist/App.d.ts.map +1 -1
- package/dist/App.js +97 -185
- package/dist/App.js.map +1 -1
- package/dist/ComponentSection.d.ts +15 -0
- package/dist/ComponentSection.d.ts.map +1 -0
- package/dist/ComponentSection.js +25 -0
- package/dist/ComponentSection.js.map +1 -0
- package/dist/ErrorBoundary.d.ts +18 -0
- package/dist/ErrorBoundary.d.ts.map +1 -0
- package/dist/ErrorBoundary.js +18 -0
- package/dist/ErrorBoundary.js.map +1 -0
- package/dist/Inspector.d.ts +1 -0
- package/dist/Inspector.d.ts.map +1 -1
- package/dist/Inspector.js +22 -347
- package/dist/Inspector.js.map +1 -1
- package/dist/Login.d.ts +8 -0
- package/dist/Login.d.ts.map +1 -0
- package/dist/Login.js +45 -0
- package/dist/Login.js.map +1 -0
- package/dist/NodeEditor.d.ts +11 -0
- package/dist/NodeEditor.d.ts.map +1 -0
- package/dist/NodeEditor.js +157 -0
- package/dist/NodeEditor.js.map +1 -0
- package/dist/Tree.d.ts +1 -0
- package/dist/Tree.d.ts.map +1 -1
- package/dist/Tree.js +8 -27
- package/dist/Tree.js.map +1 -1
- package/dist/bind/engine.js +1 -1
- package/dist/bind/engine.js.map +1 -1
- package/dist/bind/eval.d.ts +1 -1
- package/dist/bind/eval.d.ts.map +1 -1
- package/dist/bind/hook.d.ts +1 -1
- package/dist/bind/hook.d.ts.map +1 -1
- package/dist/bind/hook.js +1 -1
- package/dist/bind/hook.js.map +1 -1
- package/dist/cache.d.ts +1 -1
- package/dist/cache.d.ts.map +1 -1
- package/dist/cache.js +9 -0
- package/dist/cache.js.map +1 -1
- package/dist/client-tree.d.ts +1 -2
- package/dist/client-tree.d.ts.map +1 -1
- package/dist/client-tree.js +12 -5
- package/dist/client-tree.js.map +1 -1
- package/dist/client.d.ts +1 -1
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +2 -4
- package/dist/client.js.map +1 -1
- package/dist/components/ConfirmDialog.d.ts +9 -0
- package/dist/components/ConfirmDialog.d.ts.map +1 -0
- package/dist/components/ConfirmDialog.js +6 -0
- package/dist/components/ConfirmDialog.js.map +1 -0
- package/dist/components/ConfirmPopover.d.ts +8 -0
- package/dist/components/ConfirmPopover.d.ts.map +1 -0
- package/dist/components/ConfirmPopover.js +9 -0
- package/dist/components/ConfirmPopover.js.map +1 -0
- package/dist/components/PathBreadcrumb.d.ts +5 -0
- package/dist/components/PathBreadcrumb.d.ts.map +1 -0
- package/dist/components/PathBreadcrumb.js +16 -0
- package/dist/components/PathBreadcrumb.js.map +1 -0
- package/dist/components/lib/utils.d.ts +3 -0
- package/dist/components/lib/utils.d.ts.map +1 -0
- package/dist/components/lib/utils.js +6 -0
- package/dist/components/lib/utils.js.map +1 -0
- package/dist/components/ui/accordion.js +1 -1
- package/dist/components/ui/accordion.js.map +1 -1
- package/dist/components/ui/alert-dialog.d.ts +19 -0
- package/dist/components/ui/alert-dialog.d.ts.map +1 -0
- package/dist/components/ui/alert-dialog.js +42 -0
- package/dist/components/ui/alert-dialog.js.map +1 -0
- package/dist/components/ui/badge.js +1 -1
- package/dist/components/ui/badge.js.map +1 -1
- package/dist/components/ui/breadcrumb.d.ts +12 -0
- package/dist/components/ui/breadcrumb.d.ts.map +1 -0
- package/dist/components/ui/breadcrumb.js +28 -0
- package/dist/components/ui/breadcrumb.js.map +1 -0
- package/dist/components/ui/button.d.ts +8 -7
- package/dist/components/ui/button.d.ts.map +1 -1
- package/dist/components/ui/button.js +25 -20
- package/dist/components/ui/button.js.map +1 -1
- package/dist/components/ui/card.d.ts +10 -0
- package/dist/components/ui/card.d.ts.map +1 -0
- package/dist/components/ui/card.js +25 -0
- package/dist/components/ui/card.js.map +1 -0
- package/dist/components/ui/checkbox.js +1 -1
- package/dist/components/ui/checkbox.js.map +1 -1
- package/dist/components/ui/collapsible.d.ts +6 -0
- package/dist/components/ui/collapsible.d.ts.map +1 -0
- package/dist/components/ui/collapsible.js +13 -0
- package/dist/components/ui/collapsible.js.map +1 -0
- package/dist/components/ui/command.d.ts +19 -0
- package/dist/components/ui/command.d.ts.map +1 -0
- package/dist/components/ui/command.js +35 -0
- package/dist/components/ui/command.js.map +1 -0
- package/dist/components/ui/dialog.d.ts.map +1 -1
- package/dist/components/ui/dialog.js +1 -1
- package/dist/components/ui/dialog.js.map +1 -1
- package/dist/components/ui/drawer.js +1 -1
- package/dist/components/ui/drawer.js.map +1 -1
- package/dist/components/ui/dropdown-menu.d.ts +26 -0
- package/dist/components/ui/dropdown-menu.d.ts.map +1 -0
- package/dist/components/ui/dropdown-menu.js +52 -0
- package/dist/components/ui/dropdown-menu.js.map +1 -0
- package/dist/components/ui/form-field.d.ts +7 -0
- package/dist/components/ui/form-field.d.ts.map +1 -0
- package/dist/components/ui/form-field.js +17 -0
- package/dist/components/ui/form-field.js.map +1 -0
- package/dist/components/ui/input.js +1 -1
- package/dist/components/ui/input.js.map +1 -1
- package/dist/components/ui/label.js +1 -1
- package/dist/components/ui/label.js.map +1 -1
- package/dist/components/ui/pagination.d.ts +14 -0
- package/dist/components/ui/pagination.d.ts.map +1 -0
- package/dist/components/ui/pagination.js +30 -0
- package/dist/components/ui/pagination.js.map +1 -0
- package/dist/components/ui/popover.js +2 -2
- package/dist/components/ui/popover.js.map +1 -1
- package/dist/components/ui/progress.js +1 -1
- package/dist/components/ui/progress.js.map +1 -1
- package/dist/components/ui/resizable.d.ts +8 -0
- package/dist/components/ui/resizable.d.ts.map +1 -0
- package/dist/components/ui/resizable.js +14 -0
- package/dist/components/ui/resizable.js.map +1 -0
- package/dist/components/ui/scroll-area.d.ts +6 -0
- package/dist/components/ui/scroll-area.d.ts.map +1 -0
- package/dist/components/ui/scroll-area.js +13 -0
- package/dist/components/ui/scroll-area.js.map +1 -0
- package/dist/components/ui/select.js +1 -1
- package/dist/components/ui/select.js.map +1 -1
- package/dist/components/ui/separator.d.ts +5 -0
- package/dist/components/ui/separator.d.ts.map +1 -0
- package/dist/components/ui/separator.js +9 -0
- package/dist/components/ui/separator.js.map +1 -0
- package/dist/components/ui/sheet.d.ts +15 -0
- package/dist/components/ui/sheet.d.ts.map +1 -0
- package/dist/components/ui/sheet.js +40 -0
- package/dist/components/ui/sheet.js.map +1 -0
- package/dist/components/ui/skeleton.d.ts +3 -0
- package/dist/components/ui/skeleton.d.ts.map +1 -0
- package/dist/components/ui/skeleton.js +7 -0
- package/dist/components/ui/skeleton.js.map +1 -0
- package/dist/components/ui/slider.js +1 -1
- package/dist/components/ui/slider.js.map +1 -1
- package/dist/components/ui/switch.js +1 -1
- package/dist/components/ui/switch.js.map +1 -1
- package/dist/components/ui/table.d.ts +11 -0
- package/dist/components/ui/table.d.ts.map +1 -0
- package/dist/components/ui/table.js +29 -0
- package/dist/components/ui/table.js.map +1 -0
- package/dist/components/ui/tabs.d.ts +12 -0
- package/dist/components/ui/tabs.d.ts.map +1 -0
- package/dist/components/ui/tabs.js +29 -0
- package/dist/components/ui/tabs.js.map +1 -0
- package/dist/components/ui/textarea.js +2 -2
- package/dist/components/ui/textarea.js.map +1 -1
- package/dist/components/ui/toggle-group.d.ts +10 -0
- package/dist/components/ui/toggle-group.d.ts.map +1 -0
- package/dist/components/ui/toggle-group.js +23 -0
- package/dist/components/ui/toggle-group.js.map +1 -0
- package/dist/components/ui/toggle.d.ts +10 -0
- package/dist/components/ui/toggle.d.ts.map +1 -0
- package/dist/components/ui/toggle.js +27 -0
- package/dist/components/ui/toggle.js.map +1 -0
- package/dist/components/ui/tooltip.js +1 -1
- package/dist/components/ui/tooltip.js.map +1 -1
- package/dist/context/index.d.ts +27 -10
- package/dist/context/index.d.ts.map +1 -1
- package/dist/context/index.js +43 -36
- package/dist/context/index.js.map +1 -1
- package/dist/events.d.ts +12 -0
- package/dist/events.d.ts.map +1 -0
- package/dist/events.js +123 -0
- package/dist/events.js.map +1 -0
- package/dist/fiber-tree.d.ts +3 -0
- package/dist/fiber-tree.d.ts.map +1 -0
- package/dist/fiber-tree.js +93 -0
- package/dist/fiber-tree.js.map +1 -0
- package/dist/hooks.d.ts +14 -2
- package/dist/hooks.d.ts.map +1 -1
- package/dist/hooks.js +146 -11
- package/dist/hooks.js.map +1 -1
- package/dist/idb.d.ts +1 -1
- package/dist/idb.d.ts.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/lib/to-plain.d.ts +2 -0
- package/dist/lib/to-plain.d.ts.map +1 -0
- package/dist/lib/to-plain.js +21 -0
- package/dist/lib/to-plain.js.map +1 -0
- package/dist/main.d.ts +1 -1
- package/dist/main.d.ts.map +1 -1
- package/dist/main.js +11 -4
- package/dist/main.js.map +1 -1
- package/dist/mods/clients.d.ts +3 -0
- package/dist/mods/clients.d.ts.map +1 -0
- package/dist/mods/clients.js +4 -0
- package/dist/mods/clients.js.map +1 -0
- package/dist/mods/editor-ui/FieldLabel.d.ts +15 -0
- package/dist/mods/editor-ui/FieldLabel.d.ts.map +1 -0
- package/dist/mods/editor-ui/FieldLabel.js +56 -0
- package/dist/mods/editor-ui/FieldLabel.js.map +1 -0
- package/dist/mods/editor-ui/client.d.ts +1 -1
- package/dist/mods/editor-ui/client.d.ts.map +1 -1
- package/dist/mods/editor-ui/client.js +1 -1
- package/dist/mods/editor-ui/client.js.map +1 -1
- package/dist/mods/editor-ui/default-edit.d.ts +2 -0
- package/dist/mods/editor-ui/default-edit.d.ts.map +1 -0
- package/dist/mods/editor-ui/default-edit.js +56 -0
- package/dist/mods/editor-ui/default-edit.js.map +1 -0
- package/dist/mods/editor-ui/default-view.d.ts +8 -1
- package/dist/mods/editor-ui/default-view.d.ts.map +1 -1
- package/dist/mods/editor-ui/default-view.js +8 -5
- package/dist/mods/editor-ui/default-view.js.map +1 -1
- package/dist/mods/editor-ui/dir-view.js +0 -2
- package/dist/mods/editor-ui/dir-view.js.map +1 -1
- package/dist/mods/editor-ui/empty-placeholder.d.ts +5 -0
- package/dist/mods/editor-ui/empty-placeholder.d.ts.map +1 -0
- package/dist/mods/editor-ui/empty-placeholder.js +14 -0
- package/dist/mods/editor-ui/empty-placeholder.js.map +1 -0
- package/dist/mods/editor-ui/form-field.d.ts +17 -0
- package/dist/mods/editor-ui/form-field.d.ts.map +1 -0
- package/dist/mods/editor-ui/form-field.js +69 -0
- package/dist/mods/editor-ui/form-field.js.map +1 -0
- package/dist/mods/editor-ui/form-fields.d.ts +1 -2
- package/dist/mods/editor-ui/form-fields.d.ts.map +1 -1
- package/dist/mods/editor-ui/form-fields.js +56 -60
- package/dist/mods/editor-ui/form-fields.js.map +1 -1
- package/dist/mods/editor-ui/layout-view.js +3 -2
- package/dist/mods/editor-ui/layout-view.js.map +1 -1
- package/dist/mods/editor-ui/list-items.js +1 -1
- package/dist/mods/editor-ui/list-items.js.map +1 -1
- package/dist/mods/editor-ui/node-utils.d.ts +2 -2
- package/dist/mods/editor-ui/node-utils.d.ts.map +1 -1
- package/dist/mods/editor-ui/node-utils.js +4 -5
- package/dist/mods/editor-ui/node-utils.js.map +1 -1
- package/dist/mods/editor-ui/type-picker.d.ts +15 -0
- package/dist/mods/editor-ui/type-picker.d.ts.map +1 -0
- package/dist/mods/editor-ui/type-picker.js +70 -0
- package/dist/mods/editor-ui/type-picker.js.map +1 -0
- package/dist/mods/editor-ui/user-view.js +1 -1
- package/dist/mods/editor-ui/user-view.js.map +1 -1
- package/dist/mods/servers.d.ts +1 -0
- package/dist/mods/servers.d.ts.map +1 -0
- package/dist/mods/servers.js +4 -0
- package/dist/mods/servers.js.map +1 -0
- package/dist/mods/treenity/groups/index.js +1 -1
- package/dist/mods/treenity/groups/index.js.map +1 -1
- package/dist/mods/treenity/preview.d.ts.map +1 -1
- package/dist/mods/treenity/preview.js +3 -4
- package/dist/mods/treenity/preview.js.map +1 -1
- package/dist/mods/treenity/ref-view.js +3 -2
- package/dist/mods/treenity/ref-view.js.map +1 -1
- package/dist/mods/treenity/schema-form.js +1 -1
- package/dist/mods/treenity/schema-form.js.map +1 -1
- package/dist/mods/treenity/seed.js +3 -2
- package/dist/mods/treenity/seed.js.map +1 -1
- package/dist/mods/treenity/type-view.js +1 -1
- package/dist/mods/treenity/type-view.js.map +1 -1
- package/dist/schema-loader.d.ts +1 -1
- package/dist/schema-loader.d.ts.map +1 -1
- package/dist/schema-loader.js +1 -1
- package/dist/schema-loader.js.map +1 -1
- package/dist/symbols.d.ts +5 -0
- package/dist/symbols.d.ts.map +1 -0
- package/dist/symbols.js +22 -0
- package/dist/symbols.js.map +1 -0
- package/dist/trpc.d.ts +10 -3
- package/dist/trpc.d.ts.map +1 -1
- package/package.json +76 -8
- package/src/AclEditor.tsx +11 -18
- package/src/ActionCards.tsx +224 -0
- package/src/App.tsx +232 -385
- package/src/ComponentSection.tsx +113 -0
- package/src/ErrorBoundary.tsx +40 -0
- package/src/Inspector.css +54 -0
- package/src/Inspector.tsx +73 -793
- package/src/Login.tsx +97 -0
- package/src/NodeEditor.tsx +300 -0
- package/src/Tree.css +91 -0
- package/src/Tree.tsx +40 -43
- package/src/bind/engine.ts +1 -1
- package/src/bind/eval.ts +1 -1
- package/src/bind/hook.ts +1 -1
- package/src/bind/pipes.ts +1 -1
- package/src/cache.ts +12 -1
- package/src/client-tree.ts +18 -12
- package/src/client.ts +2 -4
- package/src/components/ConfirmDialog.tsx +34 -0
- package/src/components/ConfirmPopover.tsx +41 -0
- package/src/components/PathBreadcrumb.tsx +36 -0
- package/src/components/lib/utils.ts +6 -0
- package/src/components/lib/utils.ts.bak +6 -0
- package/src/components/ui/accordion.tsx +1 -1
- package/src/components/ui/alert-dialog.tsx +189 -0
- package/src/components/ui/badge.tsx +1 -1
- package/src/components/ui/breadcrumb.tsx +108 -0
- package/src/components/ui/button.tsx +51 -30
- package/src/components/ui/card.tsx +91 -0
- package/src/components/ui/checkbox.tsx +1 -1
- package/src/components/ui/collapsible.tsx +31 -0
- package/src/components/ui/command.tsx +177 -0
- package/src/components/ui/dialog.tsx +1 -2
- package/src/components/ui/drawer.tsx +1 -1
- package/src/components/ui/dropdown-menu.tsx +256 -0
- package/src/components/ui/form-field.tsx +37 -0
- package/src/components/ui/input.tsx +1 -1
- package/src/components/ui/label.tsx +1 -1
- package/src/components/ui/pagination.tsx +122 -0
- package/src/components/ui/popover.tsx +2 -2
- package/src/components/ui/progress.tsx +1 -1
- package/src/components/ui/resizable.tsx +47 -0
- package/src/components/ui/scroll-area.tsx +55 -0
- package/src/components/ui/select.tsx +1 -1
- package/src/components/ui/separator.tsx +27 -0
- package/src/components/ui/sheet.tsx +140 -0
- package/src/components/ui/skeleton.tsx +13 -0
- package/src/components/ui/slider.tsx +1 -1
- package/src/components/ui/switch.tsx +1 -1
- package/src/components/ui/table.tsx +115 -0
- package/src/components/ui/tabs.tsx +88 -0
- package/src/components/ui/textarea.tsx +2 -2
- package/src/components/ui/toggle-group.tsx +82 -0
- package/src/components/ui/toggle.tsx +46 -0
- package/src/components/ui/tooltip.tsx +1 -1
- package/src/context/index.tsx +75 -42
- package/src/events.ts +121 -0
- package/src/fiber-tree.ts +112 -0
- package/src/hooks.ts +161 -13
- package/src/idb.ts +1 -1
- package/src/lib/minimd.ts +7 -1
- package/src/lib/sanitize-href.ts +13 -0
- package/src/lib/to-plain.ts +21 -0
- package/src/main.tsx +14 -4
- package/src/mods/clients.ts +3 -0
- package/src/mods/editor-ui/FieldLabel.tsx +125 -0
- package/src/mods/editor-ui/client.ts +1 -1
- package/src/mods/editor-ui/default-edit.tsx +101 -0
- package/src/mods/editor-ui/default-view.tsx +13 -8
- package/src/mods/editor-ui/dir-view.tsx +2 -2
- package/src/mods/editor-ui/editor-ui.css +174 -0
- package/src/mods/editor-ui/empty-placeholder.tsx +39 -0
- package/src/mods/editor-ui/form-field.tsx +146 -0
- package/src/mods/editor-ui/form-fields.tsx +132 -113
- package/src/mods/editor-ui/layout-view.tsx +4 -2
- package/src/mods/editor-ui/list-items.tsx +2 -2
- package/src/mods/editor-ui/node-utils.ts +4 -5
- package/src/mods/editor-ui/type-picker.tsx +148 -0
- package/src/mods/editor-ui/user-view.tsx +1 -1
- package/src/mods/servers.ts +2 -0
- package/src/mods/treenity/groups/index.tsx +1 -1
- package/src/mods/treenity/preview.tsx +7 -8
- package/src/mods/treenity/ref-view.tsx +12 -7
- package/src/mods/treenity/schema-form.tsx +1 -1
- package/src/mods/treenity/seed.ts +3 -2
- package/src/mods/treenity/type-view.tsx +1 -1
- package/src/remote-tree.ts +1 -1
- package/src/root.css +117 -0
- package/src/schema-loader.ts +1 -1
- package/src/symbols.ts +25 -0
- 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/index.html +0 -14
- package/src/remote-tree.test.ts +0 -142
- package/src/style.css +0 -1269
- package/src/vite-env.d.ts +0 -3
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
|
|
3
|
+
import { cn } from '#components/lib/utils';
|
|
4
|
+
import { toggleVariants } from '#components/ui/toggle';
|
|
5
|
+
import { type VariantProps } from 'class-variance-authority';
|
|
6
|
+
import { ToggleGroup as ToggleGroupPrimitive } from 'radix-ui';
|
|
7
|
+
import * as React from 'react';
|
|
8
|
+
|
|
9
|
+
const ToggleGroupContext = React.createContext<
|
|
10
|
+
VariantProps<typeof toggleVariants> & {
|
|
11
|
+
spacing?: number
|
|
12
|
+
}
|
|
13
|
+
>({
|
|
14
|
+
size: "default",
|
|
15
|
+
variant: "default",
|
|
16
|
+
spacing: 0,
|
|
17
|
+
})
|
|
18
|
+
|
|
19
|
+
function ToggleGroup({
|
|
20
|
+
className,
|
|
21
|
+
variant,
|
|
22
|
+
size,
|
|
23
|
+
spacing = 0,
|
|
24
|
+
children,
|
|
25
|
+
...props
|
|
26
|
+
}: React.ComponentProps<typeof ToggleGroupPrimitive.Root> &
|
|
27
|
+
VariantProps<typeof toggleVariants> & {
|
|
28
|
+
spacing?: number
|
|
29
|
+
}) {
|
|
30
|
+
return (
|
|
31
|
+
<ToggleGroupPrimitive.Root
|
|
32
|
+
data-slot="toggle-group"
|
|
33
|
+
data-variant={variant}
|
|
34
|
+
data-size={size}
|
|
35
|
+
data-spacing={spacing}
|
|
36
|
+
style={{ "--gap": spacing } as React.CSSProperties}
|
|
37
|
+
className={cn(
|
|
38
|
+
"group/toggle-group flex w-fit items-center gap-[--spacing(var(--gap))] rounded-md data-[spacing=default]:data-[variant=outline]:shadow-xs",
|
|
39
|
+
className
|
|
40
|
+
)}
|
|
41
|
+
{...props}
|
|
42
|
+
>
|
|
43
|
+
<ToggleGroupContext.Provider value={{ variant, size, spacing }}>
|
|
44
|
+
{children}
|
|
45
|
+
</ToggleGroupContext.Provider>
|
|
46
|
+
</ToggleGroupPrimitive.Root>
|
|
47
|
+
)
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
function ToggleGroupItem({
|
|
51
|
+
className,
|
|
52
|
+
children,
|
|
53
|
+
variant,
|
|
54
|
+
size,
|
|
55
|
+
...props
|
|
56
|
+
}: React.ComponentProps<typeof ToggleGroupPrimitive.Item> &
|
|
57
|
+
VariantProps<typeof toggleVariants>) {
|
|
58
|
+
const context = React.useContext(ToggleGroupContext)
|
|
59
|
+
|
|
60
|
+
return (
|
|
61
|
+
<ToggleGroupPrimitive.Item
|
|
62
|
+
data-slot="toggle-group-item"
|
|
63
|
+
data-variant={context.variant || variant}
|
|
64
|
+
data-size={context.size || size}
|
|
65
|
+
data-spacing={context.spacing}
|
|
66
|
+
className={cn(
|
|
67
|
+
toggleVariants({
|
|
68
|
+
variant: context.variant || variant,
|
|
69
|
+
size: context.size || size,
|
|
70
|
+
}),
|
|
71
|
+
"w-auto min-w-0 shrink-0 px-3 focus:z-10 focus-visible:z-10",
|
|
72
|
+
"data-[spacing=0]:rounded-none data-[spacing=0]:shadow-none data-[spacing=0]:first:rounded-l-md data-[spacing=0]:last:rounded-r-md data-[spacing=0]:data-[variant=outline]:border-l-0 data-[spacing=0]:data-[variant=outline]:first:border-l",
|
|
73
|
+
className
|
|
74
|
+
)}
|
|
75
|
+
{...props}
|
|
76
|
+
>
|
|
77
|
+
{children}
|
|
78
|
+
</ToggleGroupPrimitive.Item>
|
|
79
|
+
)
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
export { ToggleGroup, ToggleGroupItem }
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
|
|
3
|
+
import { cn } from '#components/lib/utils';
|
|
4
|
+
import { cva, type VariantProps } from 'class-variance-authority';
|
|
5
|
+
import { Toggle as TogglePrimitive } from 'radix-ui';
|
|
6
|
+
import * as React from 'react';
|
|
7
|
+
|
|
8
|
+
const toggleVariants = cva(
|
|
9
|
+
"inline-flex items-center justify-center gap-2 rounded-md text-sm font-medium whitespace-nowrap transition-[color,box-shadow] outline-none hover:bg-muted hover:text-muted-foreground focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 disabled:pointer-events-none disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-destructive/20 data-[state=on]:bg-accent data-[state=on]:text-accent-foreground dark:aria-invalid:ring-destructive/40 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
|
|
10
|
+
{
|
|
11
|
+
variants: {
|
|
12
|
+
variant: {
|
|
13
|
+
default: "bg-transparent",
|
|
14
|
+
outline:
|
|
15
|
+
"border border-input bg-transparent shadow-xs hover:bg-accent hover:text-accent-foreground",
|
|
16
|
+
},
|
|
17
|
+
size: {
|
|
18
|
+
default: "h-9 min-w-9 px-2",
|
|
19
|
+
sm: "h-8 min-w-8 px-1.5",
|
|
20
|
+
lg: "h-10 min-w-10 px-2.5",
|
|
21
|
+
},
|
|
22
|
+
},
|
|
23
|
+
defaultVariants: {
|
|
24
|
+
variant: "default",
|
|
25
|
+
size: "default",
|
|
26
|
+
},
|
|
27
|
+
}
|
|
28
|
+
)
|
|
29
|
+
|
|
30
|
+
function Toggle({
|
|
31
|
+
className,
|
|
32
|
+
variant,
|
|
33
|
+
size,
|
|
34
|
+
...props
|
|
35
|
+
}: React.ComponentProps<typeof TogglePrimitive.Root> &
|
|
36
|
+
VariantProps<typeof toggleVariants>) {
|
|
37
|
+
return (
|
|
38
|
+
<TogglePrimitive.Root
|
|
39
|
+
data-slot="toggle"
|
|
40
|
+
className={cn(toggleVariants({ variant, size, className }))}
|
|
41
|
+
{...props}
|
|
42
|
+
/>
|
|
43
|
+
)
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
export { Toggle, toggleVariants }
|
package/src/context/index.tsx
CHANGED
|
@@ -2,6 +2,8 @@
|
|
|
2
2
|
// <Render> + <RenderContext> + <NodeProvider>
|
|
3
3
|
// Depends on: core (resolve), React
|
|
4
4
|
|
|
5
|
+
import { execute } from '#hooks';
|
|
6
|
+
import { $key, $node } from '#symbols';
|
|
5
7
|
import {
|
|
6
8
|
type ComponentData,
|
|
7
9
|
hasMissResolver,
|
|
@@ -9,8 +11,8 @@ import {
|
|
|
9
11
|
resolve,
|
|
10
12
|
resolveExact,
|
|
11
13
|
subscribeRegistry,
|
|
12
|
-
} from '@treenity/core
|
|
13
|
-
import { createContext, createElement, type FC, type ReactNode, useContext, useEffect, useState } from 'react';
|
|
14
|
+
} from '@treenity/core';
|
|
15
|
+
import { createContext, createElement, type FC, type ReactNode, useContext, useEffect, useMemo, useState } from 'react';
|
|
14
16
|
|
|
15
17
|
// ── Tree context (rendering context string) ──
|
|
16
18
|
|
|
@@ -28,7 +30,7 @@ export function RenderContext({ name, children }: { name: string; children: Reac
|
|
|
28
30
|
|
|
29
31
|
const NodeCtx = createContext<NodeData | null>(null);
|
|
30
32
|
|
|
31
|
-
export function NodeProvider({ value, children }: { value: NodeData | null; children
|
|
33
|
+
export function NodeProvider({ value, children }: { value: NodeData | null; children?: ReactNode }) {
|
|
32
34
|
if (!value?.$path) return null;
|
|
33
35
|
return <NodeCtx.Provider value={value}>{children}</NodeCtx.Provider>;
|
|
34
36
|
}
|
|
@@ -39,32 +41,67 @@ export function useCurrentNode(): NodeData {
|
|
|
39
41
|
return n;
|
|
40
42
|
}
|
|
41
43
|
|
|
44
|
+
// ── viewCtx — derive location context from value's symbol metadata ──
|
|
45
|
+
|
|
46
|
+
export type ViewCtx = {
|
|
47
|
+
node: NodeData;
|
|
48
|
+
path: string;
|
|
49
|
+
execute(action: string, data?: unknown): Promise<unknown>;
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
export function viewCtx(value: ComponentData): ViewCtx | null {
|
|
53
|
+
const node: NodeData | undefined = (value as any)[$node];
|
|
54
|
+
if (!node) return null;
|
|
55
|
+
const key: string = (value as any)[$key] ?? '';
|
|
56
|
+
const path = key ? `${node.$path}#${key}` : node.$path;
|
|
57
|
+
return { node, path, execute: (action, data?) => execute(path, action, data) };
|
|
58
|
+
}
|
|
59
|
+
|
|
42
60
|
// ── Handler type for React context ──
|
|
43
61
|
// value is ComponentData (base type). NodeData IS ComponentData.
|
|
44
|
-
// Renderers that need $path use usePath().
|
|
45
62
|
|
|
46
|
-
export type RenderProps = {
|
|
47
|
-
value:
|
|
48
|
-
onChange?: (next:
|
|
63
|
+
export type RenderProps<T = ComponentData> = {
|
|
64
|
+
value: T;
|
|
65
|
+
onChange?: (next: T) => void;
|
|
66
|
+
ctx?: ViewCtx | null;
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
export type ReactHandler = FC<RenderProps<any>>;
|
|
70
|
+
|
|
71
|
+
/** Typed view component. Use: `const MyView: View<MyType> = ({ value, ctx }) => ...` */
|
|
72
|
+
export type View<T> = FC<RenderProps<T>>;
|
|
73
|
+
|
|
74
|
+
// ── useActions — proxy that turns value's symbol metadata into action calls ──
|
|
75
|
+
|
|
76
|
+
type Actions<T> = {
|
|
77
|
+
[K in keyof T as T[K] extends (...args: any[]) => any ? K : never]:
|
|
78
|
+
T[K] extends (data: infer D) => any
|
|
79
|
+
? (data: D) => Promise<unknown>
|
|
80
|
+
: () => Promise<unknown>;
|
|
49
81
|
};
|
|
50
82
|
|
|
51
|
-
export
|
|
83
|
+
export function useActions<T extends ComponentData>(value: T): Actions<T> {
|
|
84
|
+
const ctx = viewCtx(value);
|
|
85
|
+
if (!ctx) throw new Error('useActions: value has no node context (missing $node symbol)');
|
|
86
|
+
|
|
87
|
+
return useMemo(() => new Proxy({} as Actions<T>, {
|
|
88
|
+
get: (_target, prop: string) => (data?: unknown) => ctx.execute(prop, data),
|
|
89
|
+
}), [ctx.path]);
|
|
90
|
+
}
|
|
52
91
|
|
|
53
92
|
declare module '@treenity/core/core/context' {
|
|
54
|
-
interface ContextHandlers {
|
|
55
|
-
react:
|
|
93
|
+
interface ContextHandlers<T> {
|
|
94
|
+
react: FC<RenderProps<T>>;
|
|
56
95
|
}
|
|
57
96
|
}
|
|
58
97
|
|
|
59
|
-
// ──
|
|
98
|
+
// ── UixNoView — registered by UIX when a type has no custom view yet ──
|
|
60
99
|
// Renders default@context without going through type-specific resolve (avoids infinite loop).
|
|
61
|
-
export const
|
|
100
|
+
export const UixNoView: FC<RenderProps> = ({ value, onChange }) => {
|
|
62
101
|
const context = useTreeContext();
|
|
63
102
|
const def = resolve('default', context, false) as FC<RenderProps> | null;
|
|
64
103
|
if (!def) return null;
|
|
65
|
-
|
|
66
|
-
if ('$path' in value) return <NodeProvider value={value as NodeData}>{el}</NodeProvider>;
|
|
67
|
-
return el;
|
|
104
|
+
return createElement(def, { value, onChange });
|
|
68
105
|
};
|
|
69
106
|
|
|
70
107
|
// ── <Render> — component/node-level rendering ──
|
|
@@ -73,40 +110,36 @@ export function Render({ value, onChange }: RenderProps) {
|
|
|
73
110
|
const context = useTreeContext();
|
|
74
111
|
const type = value.$type;
|
|
75
112
|
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
const [
|
|
79
|
-
() => resolveExact(type, context) as ReactHandler | null,
|
|
80
|
-
);
|
|
113
|
+
const ctx_ = context as 'react';
|
|
114
|
+
const sync = useMemo(() => resolveExact(type, ctx_), [type, ctx_]);
|
|
115
|
+
const [async_, setAsync] = useState<ReactHandler | null>(null);
|
|
81
116
|
|
|
82
|
-
// Subscribe to registry bumps. When handler is registered async (UIX lazy load),
|
|
83
|
-
// the callback fires and stores the resolved handler → triggers re-render.
|
|
84
117
|
useEffect(() => {
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
const h = resolveExact(type,
|
|
91
|
-
if (h)
|
|
118
|
+
if (sync) return;
|
|
119
|
+
setAsync(null);
|
|
120
|
+
if (hasMissResolver(ctx_)) resolve(type, ctx_);
|
|
121
|
+
|
|
122
|
+
return subscribeRegistry(() => {
|
|
123
|
+
const h = resolveExact(type, ctx_);
|
|
124
|
+
if (h) setAsync(() => h);
|
|
92
125
|
});
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
resolve(type, context);
|
|
126
|
+
}, [type, ctx_, sync]);
|
|
127
|
+
|
|
128
|
+
let Handler = sync ?? async_;
|
|
129
|
+
|
|
130
|
+
if (!Handler) {
|
|
131
|
+
if (hasMissResolver(ctx_)) {
|
|
132
|
+
resolve(type, ctx_);
|
|
101
133
|
return null;
|
|
102
134
|
}
|
|
103
|
-
|
|
135
|
+
Handler = resolve(type, ctx_, false);
|
|
104
136
|
}
|
|
105
137
|
|
|
106
|
-
if (!
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
138
|
+
if (!Handler) return null;
|
|
139
|
+
|
|
140
|
+
const ctx = viewCtx(value);
|
|
141
|
+
const el = createElement(Handler, { value, onChange, ctx });
|
|
142
|
+
return ctx?.node ? createElement(NodeProvider, { value: ctx.node }, el) : el;
|
|
110
143
|
}
|
|
111
144
|
|
|
112
145
|
// ── <RenderField> — field-level rendering by type name ──
|
package/src/events.ts
ADDED
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
// Server event subscription — module-level, not tied to any React component.
|
|
2
|
+
// Listens to trpc.events SSE and updates the cache.
|
|
3
|
+
|
|
4
|
+
import type { NodeData } from '@treenity/core';
|
|
5
|
+
import { applyPatch, type Operation } from 'fast-json-patch';
|
|
6
|
+
import * as cache from './cache';
|
|
7
|
+
import { trpc } from './trpc';
|
|
8
|
+
|
|
9
|
+
type LoadChildren = (path: string) => Promise<void>;
|
|
10
|
+
|
|
11
|
+
interface EventsConfig {
|
|
12
|
+
loadChildren: LoadChildren;
|
|
13
|
+
getExpanded: () => Set<string>;
|
|
14
|
+
getSelected: () => string | null;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
// ── SSE connection events (consumed by App.tsx) ──
|
|
18
|
+
|
|
19
|
+
export const SSE_CONNECTED = 'sse-connected';
|
|
20
|
+
export const SSE_DISCONNECTED = 'sse-disconnected';
|
|
21
|
+
|
|
22
|
+
let unsub: (() => void) | null = null;
|
|
23
|
+
let reconnectTimer: ReturnType<typeof setTimeout> | null = null;
|
|
24
|
+
let lastConfig: EventsConfig | null = null;
|
|
25
|
+
|
|
26
|
+
export function startEvents(config: EventsConfig) {
|
|
27
|
+
stopEvents();
|
|
28
|
+
lastConfig = config;
|
|
29
|
+
|
|
30
|
+
const { loadChildren, getExpanded, getSelected } = config;
|
|
31
|
+
|
|
32
|
+
const sub = trpc.events.subscribe(undefined as void, {
|
|
33
|
+
onStarted() {
|
|
34
|
+
window.dispatchEvent(new Event(SSE_CONNECTED));
|
|
35
|
+
},
|
|
36
|
+
onConnectionStateChange(state: { state: string }) {
|
|
37
|
+
if (state.state === 'connecting') {
|
|
38
|
+
window.dispatchEvent(new Event(SSE_DISCONNECTED));
|
|
39
|
+
} else if (state.state === 'pending') {
|
|
40
|
+
// 'pending' = connected and waiting for data — SSE is alive
|
|
41
|
+
window.dispatchEvent(new Event(SSE_CONNECTED));
|
|
42
|
+
}
|
|
43
|
+
},
|
|
44
|
+
onError(err: unknown) {
|
|
45
|
+
console.error('[sse] subscription error (non-retryable):', err);
|
|
46
|
+
window.dispatchEvent(new Event(SSE_DISCONNECTED));
|
|
47
|
+
// tRPC exhausted retries — schedule a single delayed re-subscribe
|
|
48
|
+
scheduleResubscribe();
|
|
49
|
+
},
|
|
50
|
+
onStopped() {
|
|
51
|
+
// Server closed the stream — schedule re-subscribe
|
|
52
|
+
window.dispatchEvent(new Event(SSE_DISCONNECTED));
|
|
53
|
+
scheduleResubscribe();
|
|
54
|
+
},
|
|
55
|
+
onData(event) {
|
|
56
|
+
if (event.type === 'reconnect') {
|
|
57
|
+
if (!event.preserved) {
|
|
58
|
+
cache.signalReconnect();
|
|
59
|
+
for (const path of getExpanded()) loadChildren(path);
|
|
60
|
+
const sel = getSelected();
|
|
61
|
+
if (sel) {
|
|
62
|
+
trpc.get.query({ path: sel, watch: true }).then(n => {
|
|
63
|
+
if (n) cache.put(n as NodeData);
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
return;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
if (event.type === 'set') {
|
|
71
|
+
cache.put({ $path: event.path, ...event.node } as NodeData);
|
|
72
|
+
if (event.addVps) event.addVps.forEach((vp: string) => cache.addToParent(event.path, vp));
|
|
73
|
+
if (event.rmVps) event.rmVps.forEach((vp: string) => cache.removeFromParent(event.path, vp));
|
|
74
|
+
} else if (event.type === 'patch') {
|
|
75
|
+
const existing = cache.get(event.path);
|
|
76
|
+
if (existing && event.patches) {
|
|
77
|
+
try {
|
|
78
|
+
const patched = structuredClone(existing);
|
|
79
|
+
applyPatch(patched, event.patches as Operation[]);
|
|
80
|
+
cache.put(patched);
|
|
81
|
+
} catch (e) {
|
|
82
|
+
console.error('Failed to apply patches, fetching full node:', e);
|
|
83
|
+
trpc.get.query({ path: event.path }).then((n) => {
|
|
84
|
+
if (n) cache.put(n as NodeData);
|
|
85
|
+
});
|
|
86
|
+
}
|
|
87
|
+
} else {
|
|
88
|
+
trpc.get.query({ path: event.path }).then((n) => {
|
|
89
|
+
if (n) cache.put(n as NodeData);
|
|
90
|
+
});
|
|
91
|
+
}
|
|
92
|
+
if (event.addVps) event.addVps.forEach((vp: string) => cache.addToParent(event.path, vp));
|
|
93
|
+
if (event.rmVps) event.rmVps.forEach((vp: string) => cache.removeFromParent(event.path, vp));
|
|
94
|
+
} else if (event.type === 'remove') {
|
|
95
|
+
if (event.rmVps && event.rmVps.length > 0) {
|
|
96
|
+
event.rmVps.forEach((vp: string) => cache.removeFromParent(event.path, vp));
|
|
97
|
+
} else {
|
|
98
|
+
cache.remove(event.path);
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
},
|
|
102
|
+
});
|
|
103
|
+
|
|
104
|
+
unsub = () => sub.unsubscribe();
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
const RESUBSCRIBE_DELAY = 5_000;
|
|
108
|
+
|
|
109
|
+
function scheduleResubscribe() {
|
|
110
|
+
if (reconnectTimer || !lastConfig) return;
|
|
111
|
+
console.log(`[sse] will re-subscribe in ${RESUBSCRIBE_DELAY}ms`);
|
|
112
|
+
reconnectTimer = setTimeout(() => {
|
|
113
|
+
reconnectTimer = null;
|
|
114
|
+
if (lastConfig) startEvents(lastConfig);
|
|
115
|
+
}, RESUBSCRIBE_DELAY);
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
export function stopEvents() {
|
|
119
|
+
if (reconnectTimer) { clearTimeout(reconnectTimer); reconnectTimer = null; }
|
|
120
|
+
if (unsub) { unsub(); unsub = null; }
|
|
121
|
+
}
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
// Virtual read-only Tree over React Fiber.
|
|
2
|
+
// Walks the live Fiber tree on each query — no state, no tracking.
|
|
3
|
+
// Registered as t.mount.react — isomorphic mount, same as server-side mounts.
|
|
4
|
+
|
|
5
|
+
import type { NodeData } from '@treenity/core';
|
|
6
|
+
import { register } from '@treenity/core';
|
|
7
|
+
import type { Tree } from '@treenity/core/tree';
|
|
8
|
+
|
|
9
|
+
const PREFIX = '/local/react'
|
|
10
|
+
|
|
11
|
+
interface FiberNode {
|
|
12
|
+
$path: string
|
|
13
|
+
$type: string
|
|
14
|
+
sourcePath?: string
|
|
15
|
+
children?: FiberNode[]
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
// Detect <Render> by name + props shape (resilient to HMR wrappers)
|
|
19
|
+
function isRenderFiber(f: any): boolean {
|
|
20
|
+
if (!f.memoizedProps?.value?.$type) return false
|
|
21
|
+
const name = f.type?.name || f.type?.displayName || ''
|
|
22
|
+
return name === 'Render'
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
function getRootFiber() {
|
|
26
|
+
const el = document.getElementById('root')
|
|
27
|
+
if (!el) return null
|
|
28
|
+
|
|
29
|
+
// React 19 createRoot: __reactContainer$ on the container element
|
|
30
|
+
const containerKey = Object.keys(el).find(k => k.startsWith('__reactContainer$'))
|
|
31
|
+
if (containerKey) return (el as any)[containerKey]
|
|
32
|
+
|
|
33
|
+
// React 18 fallback: __reactFiber$ on first child
|
|
34
|
+
const fiberKey = Object.keys(el).find(k => k.startsWith('__reactFiber$'))
|
|
35
|
+
return fiberKey ? (el as any)[fiberKey] : null
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
function walk(fiber: any, parentPath: string, maxDepth: number, depth = 0): FiberNode[] {
|
|
39
|
+
if (depth >= maxDepth) return []
|
|
40
|
+
|
|
41
|
+
const result: FiberNode[] = []
|
|
42
|
+
let f = fiber?.child
|
|
43
|
+
let i = 0
|
|
44
|
+
|
|
45
|
+
while (f) {
|
|
46
|
+
if (isRenderFiber(f)) {
|
|
47
|
+
const v = f.memoizedProps.value
|
|
48
|
+
const path = `${parentPath}/${i}`
|
|
49
|
+
result.push({
|
|
50
|
+
$path: path,
|
|
51
|
+
$type: v.$type,
|
|
52
|
+
sourcePath: v.$path,
|
|
53
|
+
children: depth + 1 < maxDepth ? walk(f, path, maxDepth, depth + 1) : undefined,
|
|
54
|
+
})
|
|
55
|
+
i++
|
|
56
|
+
} else {
|
|
57
|
+
result.push(...walk(f, parentPath, maxDepth, depth))
|
|
58
|
+
}
|
|
59
|
+
f = f.sibling
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
return result
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
function scan(depth = 1): FiberNode[] {
|
|
66
|
+
const root = getRootFiber()
|
|
67
|
+
return root ? walk(root, PREFIX, depth) : []
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
function findByPath(nodes: FiberNode[], path: string): FiberNode | undefined {
|
|
71
|
+
for (const n of nodes) {
|
|
72
|
+
if (n.$path === path) return n
|
|
73
|
+
if (n.children) {
|
|
74
|
+
const found = findByPath(n.children, path)
|
|
75
|
+
if (found) return found
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
function toNode(n: FiberNode): NodeData {
|
|
81
|
+
return { $path: n.$path, $type: n.$type, sourcePath: n.sourcePath } as NodeData
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
export function createFiberTree(): Tree {
|
|
85
|
+
return {
|
|
86
|
+
async get(path) {
|
|
87
|
+
if (path === PREFIX) return { $path: PREFIX, $type: 'dir' } as NodeData
|
|
88
|
+
const node = findByPath(scan(100), path)
|
|
89
|
+
return node ? toNode(node) : undefined
|
|
90
|
+
},
|
|
91
|
+
|
|
92
|
+
async getChildren(path, opts?) {
|
|
93
|
+
const depth = opts?.depth ?? 1
|
|
94
|
+
|
|
95
|
+
if (path === PREFIX) {
|
|
96
|
+
const nodes = scan(depth)
|
|
97
|
+
return { items: nodes.map(toNode), total: nodes.length }
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
const parent = findByPath(scan(100), path)
|
|
101
|
+
const children = parent?.children ?? []
|
|
102
|
+
return { items: children.map(toNode), total: children.length }
|
|
103
|
+
},
|
|
104
|
+
|
|
105
|
+
async set() { throw new Error('fiber tree is read-only') },
|
|
106
|
+
async remove() { throw new Error('fiber tree is read-only') },
|
|
107
|
+
async patch() { throw new Error('fiber tree is read-only') },
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
// Mount adapter — same pattern as t.mount.fs, t.mount.mongo
|
|
112
|
+
register('t.mount.react', 'mount', () => createFiberTree())
|