@cosmicdrift/kumiko-framework 0.3.0 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,46 @@
|
|
|
1
1
|
# @cosmicdrift/kumiko-framework
|
|
2
2
|
|
|
3
|
+
## 0.4.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- 825e7d2: Visual-Tree V.1.4 → V.1.6 — Feature-complete Editor + Folder-Hierarchy + Roving-tabindex.
|
|
8
|
+
|
|
9
|
+
**V.1.4** — explicit `folder?: string` Schema-Field auf text-block-entity. Slug bleibt
|
|
10
|
+
kebab-only validiert, Folder explizit gesetzt. Tree gruppiert via `groupBlocksByFolder`
|
|
11
|
+
(ersetzt `groupBlocksBySlugPrefix`). `Subscribe<T>` Signature um optional `emitError`
|
|
12
|
+
erweitert für explicit async-error-Pfade. ProviderBranch zeigt Error-Banner mit
|
|
13
|
+
Retry-Button. Drift-Test pinnt seedTextBlock-vs-set.write Slug-Validation.
|
|
14
|
+
|
|
15
|
+
**V.1.4b** — URL-State-Routing für Editor-Target via `nav.searchParams`. F5 + Back-Button
|
|
16
|
+
stellen den Editor-State wieder her. Format: `?t=text-content:edit&a_slug=...&a_lang=...`.
|
|
17
|
+
Plus `useDispatchTarget` hook ersetzt globalen `dispatchTarget` als empfohlenen Production-
|
|
18
|
+
Pfad (legacy bleibt für Test-Hooks).
|
|
19
|
+
|
|
20
|
+
**V.1.5** — Arrow-Key-Navigation (`<aside role="tree">`, ARIA-tree-Pattern) + SSE-driven
|
|
21
|
+
Tree-Refresh. `ClientFeatureDefinition.treeEntities?: string[]` listet Entity-Namen pro
|
|
22
|
+
Provider; live-events triggern provider-re-mount → Stale-Tree-state="stub"→"filled"
|
|
23
|
+
flippt nach save automatisch.
|
|
24
|
+
|
|
25
|
+
**V.1.5c+d** — Active-Node-Highlight (explicit blue + 2px border-l + scrollIntoView),
|
|
26
|
+
VS-Code-Polish (compact spacing, focus-visible, folder-icon-color text-amber, indent-
|
|
27
|
+
guides per ancestor-depth), Folder-Wrapper für legal-pages ("📁 Legal" + slug-first
|
|
28
|
+
Verschachtelung) und text-content ("📁 Content").
|
|
29
|
+
|
|
30
|
+
**V.1.6** — Multi-level Folder-Splitting (`folder="page/marketing"` → nested folders,
|
|
31
|
+
walk-or-create-pattern, folder/leaf-collision-tolerant). Roving-tabindex (nur focused-
|
|
32
|
+
treeitem hat tabIndex=0, Tab cyclt aus dem Tree raus).
|
|
33
|
+
|
|
34
|
+
35/35 kumiko check PASS, 13/13 group-blocks + 22/22 text-content integration tests grün.
|
|
35
|
+
Browser + Keyboard lokal validated.
|
|
36
|
+
|
|
37
|
+
**Breaking**: `TreeContext` Type entfernt (V.1.2 SR2-Rip — war nie genutzt). Provider sind
|
|
38
|
+
session-bound: `TreeChildrenSubscribe = () => Subscribe<T>` statt `(ctx) => Subscribe<T>`.
|
|
39
|
+
|
|
40
|
+
**V.1.7-Followups**: useEffect-deps in VisualTree-focus-init (Performance), Cancellation-
|
|
41
|
+
Token in TreeProvider's fetch (emit-after-unmount-warning), inline-rename, drag-drop,
|
|
42
|
+
file-icons per slug-extension, parent-jump bei ArrowLeft auf collapsed-item.
|
|
43
|
+
|
|
3
44
|
## 0.3.0
|
|
4
45
|
|
|
5
46
|
### Minor Changes
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cosmicdrift/kumiko-framework",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.4.0",
|
|
4
4
|
"description": "Framework core — engine, pipeline, API, DB, and every other bit that makes Kumiko go.",
|
|
5
5
|
"license": "BUSL-1.1",
|
|
6
6
|
"author": "Marc Frost <marc@cosmicdriftgamestudio.com>",
|
|
@@ -159,7 +159,7 @@
|
|
|
159
159
|
"zod": "^4.4.3"
|
|
160
160
|
},
|
|
161
161
|
"devDependencies": {
|
|
162
|
-
"@cosmicdrift/kumiko-dispatcher-live": "0.
|
|
162
|
+
"@cosmicdrift/kumiko-dispatcher-live": "0.4.0",
|
|
163
163
|
"@types/uuid": "^11.0.0",
|
|
164
164
|
"bun-types": "^1.3.13",
|
|
165
165
|
"drizzle-kit": "^0.31.10",
|
package/src/engine/index.ts
CHANGED
|
@@ -573,9 +573,10 @@ export type FeatureRegistrar<TFeature extends string = string> = {
|
|
|
573
573
|
// that emits the top-level Tree-Knoten when the Visual-Workspace
|
|
574
574
|
// (navigation: "tree") mounts. At-most-one call per feature.
|
|
575
575
|
//
|
|
576
|
-
// Provider
|
|
577
|
-
// emit
|
|
578
|
-
//
|
|
576
|
+
// Provider returns a Subscribe-Function (emit-fn → unsubscribe-fn).
|
|
577
|
+
// Initial-emit synchron oder async, weitere Emits beliebig oft (e.g.
|
|
578
|
+
// on entity-update SSE). Provider sind session-bound; tenantId fließt
|
|
579
|
+
// über die Backend-Session bei fetch/dispatch, nicht über ein ctx-Arg.
|
|
579
580
|
//
|
|
580
581
|
// A feature without r.tree() is invisible in `navigation: "tree"`-
|
|
581
582
|
// workspaces — that's the Zero-Whitelist-Filter from visual-tree.md A2:
|
|
@@ -23,7 +23,6 @@
|
|
|
23
23
|
//
|
|
24
24
|
// Siehe docs/plans/architecture/visual-tree.md A4.
|
|
25
25
|
|
|
26
|
-
import type { TenantId } from "./identifiers";
|
|
27
26
|
import type { TargetRef } from "./target-ref";
|
|
28
27
|
|
|
29
28
|
export type TreeNodeState = "filled" | "stub" | "empty" | "loading" | "error";
|
|
@@ -75,25 +74,28 @@ export type TreeNode = {
|
|
|
75
74
|
// Subscribe<T> — Provider implementiert: emit(initial); ...emit(updated);
|
|
76
75
|
// und gibt unsubscribe-Function zurück. Caller (Tree-Component) ruft
|
|
77
76
|
// unsubscribe auf wenn Knoten unmounted/eingeklappt wird.
|
|
78
|
-
|
|
77
|
+
//
|
|
78
|
+
// **V.1.4 emitError**: optional callback für async-error-Pfade (fetch-
|
|
79
|
+
// fail, SSE-disconnect). Provider die explizit Errors signalisieren
|
|
80
|
+
// wollen rufen `emitError(e)` statt empty-emit; VisualTree zeigt
|
|
81
|
+
// Error-Banner mit Retry-Button. Sync-Throws im Provider-Body werden
|
|
82
|
+
// vom useEffect-try/catch abgefangen — emitError ist nur für async.
|
|
83
|
+
export type Subscribe<T> = (
|
|
84
|
+
emit: (value: T) => void,
|
|
85
|
+
emitError?: (error: Error) => void,
|
|
86
|
+
) => () => void;
|
|
79
87
|
|
|
80
88
|
// TreeChildrenSubscribe — Lazy-Variante für dynamic Children. Wird
|
|
81
|
-
// erst aufgerufen wenn der Knoten im UI ausgeklappt wird. ctx
|
|
82
|
-
//
|
|
83
|
-
//
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
//
|
|
87
|
-
//
|
|
88
|
-
//
|
|
89
|
-
//
|
|
90
|
-
|
|
91
|
-
// SSE-driven re-emit). Memory `[Keine Optionen ohne Bedarf]` — surface
|
|
92
|
-
// wächst mit Bedarfen, nicht mit Spekulation. Siehe visual-tree.md
|
|
93
|
-
// V.1.1-Decision D1.
|
|
94
|
-
export type TreeContext = Readonly<{
|
|
95
|
-
readonly tenantId: TenantId;
|
|
96
|
-
}>;
|
|
89
|
+
// erst aufgerufen wenn der Knoten im UI ausgeklappt wird. Kein ctx-
|
|
90
|
+
// Argument: Provider sind session-bound; Backend liest tenantId aus
|
|
91
|
+
// session bei jedem fetch/dispatch. V.1.1 hatte ein ctx mit tenantId,
|
|
92
|
+
// das aber im Browser nie echten Tenant trug (war auf SYSTEM_TENANT_ID
|
|
93
|
+
// gepinnt) und vom einzigen V.1.2-Consumer (text-content) ignoriert
|
|
94
|
+
// wurde. SR2-Rip 2026-05-18: Dead-API entfernt; wenn später ein
|
|
95
|
+
// Provider tenant-aware-rendern muss (z.B. cross-tenant-Dashboards
|
|
96
|
+
// für SystemAdmin), wird ctx mit echtem Tenant-Source aus dem Auth-
|
|
97
|
+
// Layer re-introduziert. YAGNI bis dahin.
|
|
98
|
+
export type TreeChildrenSubscribe = () => Subscribe<readonly TreeNode[]>;
|
|
97
99
|
|
|
98
100
|
// TreeActionDef — Schema-Eintrag pro Action in der treeActions-Map
|
|
99
101
|
// eines Features. Phase 0: Args sind ein optionales Type-Sample
|