diff --git a/README.md b/README.md
index 3ea49e38..9d6531b2 100644
--- a/README.md
+++ b/README.md
@@ -1,14 +1,15 @@
# json-document
-json-document는 Zod schema가 있는 JSON 문서를 편집하기 위한 headless document
-engine입니다.
+json-document는 문서, 표, 슬라이드, 캔버스, 노트 편집기가 함께 쓸 수 있는
+provider-neutral JSON 편집 protocol과 headless document projection입니다.
-폼, CMS block, kanban board, outliner, settings editor처럼 UI가 다른 편집 툴도
-결국 schema가 있는 JSON document를 읽고, 바꾸고, 선택하고, 복사하고,
-붙여넣고, 되돌립니다. json-document는 이 공통 document engine을 UI 밖에 둡니다.
+v2 root는 JSON, JSON Pointer, JSONPath, JSON Patch만 전제로 하며 Zod, React,
+selection, clipboard, history를 필수 계약에 넣지 않습니다.
```txt
-schema -> document -> pointer/query -> can* -> change -> result
+Pure Protocol
+ |-> Document Projection -> host adapter
+ `-> Candidate Editing Session -> React / rich host adapter
```
공식 사이트: https://developer-1px.github.io/json-document/
@@ -24,17 +25,15 @@ schema -> document -> pointer/query -> can* -> change -> result
| 제품별 feature 지도 | [docs/public/recipes.md](docs/public/recipes.md) |
| 문서 구조 | [docs/README.md](docs/README.md) |
| 변경 기록 | [docs/changelog.md](docs/changelog.md) |
-| core 의미론 명세 | [docs/standard/json-document-spec.md](docs/standard/json-document-spec.md) |
-| 1.0 conformance profile | [docs/standard/conformance-profile.md](docs/standard/conformance-profile.md) |
-| result/error 계약 | [docs/standard/result-contract.md](docs/standard/result-contract.md) |
-| selection 계약 | [docs/standard/selection-contract.md](docs/standard/selection-contract.md) |
-| schema introspection 계약 | [docs/standard/schema-introspection-contract.md](docs/standard/schema-introspection-contract.md) |
+| v2 Projection 표준 | [docs/standard/v2-projection-profile.md](docs/standard/v2-projection-profile.md) |
+| v2 공개 표면 manifest | [docs/standard/v2-public-surface.json](docs/standard/v2-public-surface.json) |
+| Candidate Session의 1.x 기준선 | [docs/standard/conformance-profile.md](docs/standard/conformance-profile.md) |
## 코드 지도
| 위치 | 역할 |
| --- | --- |
-| [packages/json-document](packages/json-document) | core package. `createJSONDocument`, JSON Patch/Pointer/Path, selection, clipboard, history |
+| [packages/json-document](packages/json-document) | v2 Kernel과 optional Candidate Session |
| [packages/collection](packages/collection) | ordered JSON array item 이동/복제/삭제 |
| [packages/clipboard-web](packages/clipboard-web) | browser clipboard bridge |
| [packages/contenteditable-web](packages/contenteditable-web) | `@interactive-os/json-document-contenteditable-web` DOM contenteditable text-surface adapter |
@@ -61,13 +60,16 @@ schema -> document -> pointer/query -> can* -> change -> result
## 경계
-json-document가 제공하는 document engine:
+v2 Kernel이 제공하는 최소 계약:
-- Zod schema로 검증되는 JSON document state
-- JSON Pointer 주소, JSON Patch mutation, JSONPath search
-- `can*` capability result
-- headless selection, clipboard payload, undo/redo history
-- 반복 편집 개념을 조립하는 작은 extension 함수
+- immutable JSON snapshot
+- JSON Pointer read와 JSONPath query
+- state를 바꾸지 않는 `canPatch`
+- ordered atomic JSON Patch commit
+- canonical applied change publication
+
+`@interactive-os/json-document/session`은 Zod 기반 schema 검증, selection,
+clipboard, history와 고수준 편집 동사를 제공하는 optional Candidate 표면입니다.
편집 툴이 계속 소유하는 것:
diff --git a/apps/grouping-lab/src/App.tsx b/apps/grouping-lab/src/App.tsx
index 6b17c630..b866da3c 100644
--- a/apps/grouping-lab/src/App.tsx
+++ b/apps/grouping-lab/src/App.tsx
@@ -1,6 +1,6 @@
import { useMemo, useState } from "react";
import { createGrouping, type GroupingAdapter, type GroupingChangeResult } from "@interactive-os/json-document-grouping";
-import type { Pointer } from "@interactive-os/json-document";
+import type { Pointer } from "@interactive-os/json-document/session";
import { useJSONDocument } from "@interactive-os/json-document/react";
import { z } from "zod";
import "./grouping-lab.css";
diff --git a/apps/outliner-blind-b/src/outlinerModel.test.ts b/apps/outliner-blind-b/src/outlinerModel.test.ts
index f2e7ef64..3d0ab23b 100644
--- a/apps/outliner-blind-b/src/outlinerModel.test.ts
+++ b/apps/outliner-blind-b/src/outlinerModel.test.ts
@@ -1,5 +1,5 @@
import { describe, expect, it } from "vitest";
-import { createJSONDocument } from "@interactive-os/json-document";
+import { createJSONDocument } from "@interactive-os/json-document/session";
import {
addChild,
addSibling,
diff --git a/apps/outliner-blind-b/src/outlinerModel.ts b/apps/outliner-blind-b/src/outlinerModel.ts
index 1621b874..02006b66 100644
--- a/apps/outliner-blind-b/src/outlinerModel.ts
+++ b/apps/outliner-blind-b/src/outlinerModel.ts
@@ -1,5 +1,5 @@
import * as z from "zod";
-import type { JSONDocument, JSONPatchOperation, Pointer } from "@interactive-os/json-document";
+import type { JSONDocument, JSONPatchOperation, Pointer } from "@interactive-os/json-document/session";
export type OutlineNode = {
id: string;
diff --git a/apps/outliner/src/OutlineRow.tsx b/apps/outliner/src/OutlineRow.tsx
index f35e6e36..a5d4b117 100644
--- a/apps/outliner/src/OutlineRow.tsx
+++ b/apps/outliner/src/OutlineRow.tsx
@@ -2,7 +2,7 @@
// keydown 은 props 로 받는다 — chord dispatcher 는 부모 책임.
import { useEffect, useRef } from "react";
-import type { JSONDocument, Pointer } from "@interactive-os/json-document";
+import type { JSONDocument, Pointer } from "@interactive-os/json-document/session";
import type { OutlineNode } from "./schema.js";
import type { Mode } from "./keymap.js";
diff --git a/apps/outliner/src/clipboard.ts b/apps/outliner/src/clipboard.ts
index df30af9e..81d893af 100644
--- a/apps/outliner/src/clipboard.ts
+++ b/apps/outliner/src/clipboard.ts
@@ -10,7 +10,7 @@ import {
type WebClipboardCutResult,
type WebClipboardPasteResult,
} from "@interactive-os/json-document-clipboard-web";
-import type { JSONDocument, Pointer } from "@interactive-os/json-document";
+import type { JSONDocument, Pointer } from "@interactive-os/json-document/session";
import type { OutlineNode } from "./schema.js";
export type ClipboardMode = "empty" | "copy" | "cut";
diff --git a/apps/outliner/src/commands/context.ts b/apps/outliner/src/commands/context.ts
index 0f70a8d8..86e35a15 100644
--- a/apps/outliner/src/commands/context.ts
+++ b/apps/outliner/src/commands/context.ts
@@ -1,6 +1,6 @@
// Command 들이 공유하는 ctx 형식 + 공용 헬퍼.
-import type { JSONDocument, Pointer, SelectionPoint, SelectionState } from "@interactive-os/json-document";
+import type { JSONDocument, Pointer, SelectionPoint, SelectionState } from "@interactive-os/json-document/session";
import type { OutlineNode } from "../schema.js";
import type { ClipboardApi } from "../clipboard.js";
import { comparePointer } from "../pointer-utils.js";
diff --git a/apps/outliner/src/commands/focus.ts b/apps/outliner/src/commands/focus.ts
index 6f191997..73ffc25f 100644
--- a/apps/outliner/src/commands/focus.ts
+++ b/apps/outliner/src/commands/focus.ts
@@ -1,6 +1,6 @@
// Focus navigation — DFS visible order 위에서 좌표 이동만 (state 미변경).
-import type { Pointer } from "@interactive-os/json-document";
+import type { Pointer } from "@interactive-os/json-document/session";
import type { OutlineNode } from "../schema.js";
import {
parentOf, nextVisible, prevVisible, firstVisible, lastVisible, firstChildOf,
diff --git a/apps/outliner/src/commands/structure.ts b/apps/outliner/src/commands/structure.ts
index bacd81a3..76568660 100644
--- a/apps/outliner/src/commands/structure.ts
+++ b/apps/outliner/src/commands/structure.ts
@@ -1,6 +1,6 @@
import { createCollection } from "@interactive-os/json-document-collection";
import { createOutline } from "@interactive-os/json-document-outline";
-import { type JSONResult, type Pointer } from "@interactive-os/json-document";
+import { type JSONResult, type Pointer } from "@interactive-os/json-document/session";
import { lastIndex, parentOf } from "../pointer-utils.js";
import { focusOf, type CommandContext, targetsOf, sortDfs } from "./context.js";
diff --git a/apps/outliner/src/hooks/useClickPolicy.ts b/apps/outliner/src/hooks/useClickPolicy.ts
index dd73fa05..f75dd122 100644
--- a/apps/outliner/src/hooks/useClickPolicy.ts
+++ b/apps/outliner/src/hooks/useClickPolicy.ts
@@ -4,7 +4,7 @@
// click = collapse
import { useCallback } from "react";
-import type { Pointer, SelectionState } from "@interactive-os/json-document";
+import type { Pointer, SelectionState } from "@interactive-os/json-document/session";
import type { Mode } from "../keymap.js";
export function useClickPolicy(
diff --git a/apps/outliner/src/hooks/useDraftState.ts b/apps/outliner/src/hooks/useDraftState.ts
index eff2bf6a..f079f3a1 100644
--- a/apps/outliner/src/hooks/useDraftState.ts
+++ b/apps/outliner/src/hooks/useDraftState.ts
@@ -5,7 +5,7 @@ import {
type DocumentPersistenceRestoreResult,
type DocumentPersistenceSaveResult,
} from "@interactive-os/json-document-persist-web";
-import type { JSONDocument } from "@interactive-os/json-document";
+import type { JSONDocument } from "@interactive-os/json-document/session";
import type { OutlineNode } from "../schema.js";
const DRAFT_KEY = "json-document.outliner.draft";
diff --git a/apps/outliner/src/hooks/useToasts.ts b/apps/outliner/src/hooks/useToasts.ts
index d772f527..4142705a 100644
--- a/apps/outliner/src/hooks/useToasts.ts
+++ b/apps/outliner/src/hooks/useToasts.ts
@@ -1,7 +1,7 @@
// Toast 상태. error 는 클릭 시까지 유지 (zod 메시지가 길어서), info 는 2.5s.
import { useCallback, useEffect, useRef, useState } from "react";
-import type { JSONDocumentError } from "@interactive-os/json-document";
+import type { JSONDocumentError } from "@interactive-os/json-document/session";
export interface ToastMessage {
id: number;
diff --git a/apps/outliner/src/pointer-utils.ts b/apps/outliner/src/pointer-utils.ts
index cd7314fd..064327b8 100644
--- a/apps/outliner/src/pointer-utils.ts
+++ b/apps/outliner/src/pointer-utils.ts
@@ -1,6 +1,6 @@
// Outliner-local Pointer helpers. RFC 6901 위에서 outline 트리를 다루는 식별 함수들.
-import { parentPointer, lastSegmentIndex, withLastSegment, type Pointer } from "@interactive-os/json-document";
+import { parentPointer, lastSegmentIndex, withLastSegment, type Pointer } from "@interactive-os/json-document/session";
import type { OutlineNode } from "./schema.js";
// Outliner-local 별칭 — json-document 의 path arithmetic 헬퍼를 짧은 이름으로.
diff --git a/apps/outliner/tests/stress.test.tsx b/apps/outliner/tests/stress.test.tsx
index f08fa429..8b670c2c 100644
--- a/apps/outliner/tests/stress.test.tsx
+++ b/apps/outliner/tests/stress.test.tsx
@@ -12,7 +12,7 @@ import { renderHook } from "@testing-library/react";
import { afterEach, describe, expect, test } from "vitest";
import { z } from "zod";
import { Outliner, OutlineSchema, SAMPLE } from "../src/index.js";
-import type { JSONDocumentError } from "@interactive-os/json-document";
+import type { JSONDocumentError } from "@interactive-os/json-document/session";
import { useJSONDocument } from "@interactive-os/json-document/react";
afterEach(cleanup);
diff --git a/apps/review-comments-lab/src/App.tsx b/apps/review-comments-lab/src/App.tsx
index 07124048..fab9678c 100644
--- a/apps/review-comments-lab/src/App.tsx
+++ b/apps/review-comments-lab/src/App.tsx
@@ -6,7 +6,7 @@ import {
type Comments,
} from "@interactive-os/json-document-comments";
import { useJSONDocument } from "@interactive-os/json-document/react";
-import { type Pointer } from "@interactive-os/json-document";
+import { type Pointer } from "@interactive-os/json-document/session";
import { z } from "zod";
import "./review-comments-lab.css";
diff --git a/apps/site/index.html b/apps/site/index.html
index 66af1565..9b72cf92 100644
--- a/apps/site/index.html
+++ b/apps/site/index.html
@@ -5,7 +5,7 @@
@@ -13,14 +13,14 @@
diff --git a/apps/site/public/site.webmanifest b/apps/site/public/site.webmanifest
index e4145643..38c1f5a2 100644
--- a/apps/site/public/site.webmanifest
+++ b/apps/site/public/site.webmanifest
@@ -1,7 +1,7 @@
{
"name": "@interactive-os/json-document",
"short_name": "@interactive-os/json-document",
- "description": "Zod-guarded headless JSON editing.",
+ "description": "Provider-neutral JSON editing protocol and headless document projection.",
"start_url": ".",
"display": "standalone",
"background_color": "#fafaf9",
diff --git a/apps/site/src/generated/repo-catalog.ts b/apps/site/src/generated/repo-catalog.ts
index e06763a1..4e2c623f 100644
--- a/apps/site/src/generated/repo-catalog.ts
+++ b/apps/site/src/generated/repo-catalog.ts
@@ -4,7 +4,7 @@ export const repoCatalog = {
"repo": {
"name": "@interactive-os/json-document-monorepo",
"private": true,
- "summary": "json-document는 Zod schema가 있는 JSON 문서를 편집하기 위한 headless document\nengine입니다."
+ "summary": "json-document는 문서, 표, 슬라이드, 캔버스, 노트 편집기가 함께 쓸 수 있는\nprovider-neutral JSON 편집 protocol과 headless document projection입니다."
},
"packages": [
{
@@ -386,163 +386,43 @@ export const repoCatalog = {
"status": "core",
"private": false,
"publishable": true,
- "version": "1.1.0-rc.0",
- "description": "Headless JSON editing primitives guarded by Zod schemas.",
+ "version": "2.0.0-rc.0",
+ "description": "Provider-neutral JSON editing protocol and headless document projection.",
"license": "MIT",
- "summary": "Zod schema로 보호되는 JSON state를 읽고, 바꾸고, 선택하고, 복사하고,\n붙여넣고, 되돌리기 위한 headless document layer입니다.",
+ "summary": "문서, 표, 슬라이드, 캔버스, 노트 편집기가 함께 쓸 수 있는 provider-neutral\nJSON 편집 protocol과 headless document projection입니다.",
"guidance": null,
"publicExports": [
- "ClipboardCopyError",
- "ClipboardCopyOk",
- "ClipboardCopyOptions",
- "ClipboardCopyResult",
- "ClipboardCutError",
- "ClipboardCutOk",
- "ClipboardCutOptions",
- "ClipboardCutResult",
- "ClipboardEmpty",
- "ClipboardMutationOk",
- "ClipboardPasteDiscriminatorMismatch",
- "ClipboardPasteError",
- "ClipboardPasteResult",
- "ClipboardReadOk",
- "ClipboardReadOptions",
- "ClipboardReadResult",
- "ClipboardSource",
- "ClipboardState",
- "ClipboardWriteOptions",
- "DeleteSelectionTextResult",
- "EntriesResult",
- "EntryKind",
- "HistoryTransactionOptions",
+ "JSONAppliedChange",
"JSONCapabilityResult",
"JSONChangeMetadata",
"JSONDocument",
"JSONDocumentCommitOptions",
- "JSONDocumentDuplicateError",
- "JSONDocumentDuplicateOptions",
- "JSONDocumentDuplicateResult",
- "JSONDocumentEditError",
- "JSONDocumentEditOk",
- "JSONDocumentEditResult",
- "JSONDocumentError",
- "JSONDocumentHistory",
- "JSONDocumentInsertOptions",
- "JSONDocumentInsertTarget",
- "JSONDocumentMoveTarget",
- "JSONDocumentOptions",
- "JSONDocumentPasteOptions",
- "JSONDocumentPasteTarget",
- "JSONDocumentSchemaInput",
- "JSONDocumentSchemaLike",
- "JSONDocumentSchemaOutput",
- "JSONDocumentSelectionTarget",
- "JSONPatchInput",
+ "JSONDocumentCommitResult",
"JSONPatchOperation",
- "JSONResult",
+ "JSONPatchResult",
+ "JSONValue",
"Pointer",
- "PointerSyntaxError",
"QueryResult",
- "ReadEntry",
"ReadResult",
- "ReplaceSelectionTextResult",
- "ResolveSiblingRangeOptions",
- "SchemaDescription",
- "SchemaDescriptionResult",
- "SchemaErrorCode",
- "SchemaErrorResult",
- "SchemaKind",
- "SchemaKindResult",
- "SchemaPathMode",
- "SchemaQueryResult",
- "SchemaState",
- "SelectionAffinity",
- "SelectionContext",
- "SelectionCursorDirection",
- "SelectionCursorErrorCode",
- "SelectionCursorOptions",
- "SelectionCursorResult",
- "SelectionCursorTarget",
- "SelectionDirection",
- "SelectionEdge",
- "SelectionMode",
- "SelectionOptions",
- "SelectionOrderErrorCode",
- "SelectionOrderOptions",
- "SelectionOrderedRange",
- "SelectionOrderedRangeEntry",
- "SelectionPoint",
- "SelectionPointObject",
- "SelectionPointOrderResult",
- "SelectionPointerSpan",
- "SelectionPointerSpansResult",
- "SelectionRange",
- "SelectionRangeInput",
- "SelectionRangeOrderResult",
- "SelectionRangesOrderResult",
- "SelectionScopeErrorCode",
- "SelectionScopeOptions",
- "SelectionScopeResult",
- "SelectionScopeTarget",
- "SelectionSnap",
- "SelectionSource",
- "SelectionSpanOptions",
- "SelectionState",
- "SelectionTextDeleteDirection",
- "SelectionTextDeleteOptions",
- "SelectionTextEdit",
- "SelectionTextEditErrorCode",
- "SelectionTextEditOptions",
- "SelectionTextEditsResult",
- "SelectionType",
- "SiblingLocation",
- "SiblingRangeErrorCode",
- "SiblingRangeResult",
- "TextSurface",
- "TextSurfaceAtom",
- "TextSurfaceError",
- "TextSurfaceErrorCode",
- "TextSurfaceFragment",
- "TextSurfaceFragmentResult",
- "TextSurfaceMutationRange",
- "TextSurfaceMutationResult",
- "TextSurfaceRange",
- "TextSurfaceReplaceOptions",
- "TextSurfaceReplaceResult",
- "TextSurfaceReplacement",
- "TextSurfaceSelectionRange",
"appendSegment",
- "applyOperation",
"applyPatch",
- "applyPatchToTrustedState",
"buildPointer",
"createJSONDocument",
- "escapeSegment",
- "lastSegment",
- "lastSegmentIndex",
"parentPointer",
"parsePointer",
- "replaceTextSurfaceSelection",
- "resolveSiblingRange",
- "syncTextSurfaceMutation",
- "textSurfaceFragment",
"trackPointer",
- "tryParsePointer",
- "unescapeSegment",
- "withLastSegment"
+ "tryParsePointer"
],
- "publicExportCount": 138,
+ "publicExportCount": 20,
"keywords": [
- "clipboard",
- "crud",
+ "document",
+ "editor",
"headless",
"json",
- "redo",
- "schema",
- "tree",
- "treegrid",
- "undo",
- "zod"
+ "json-patch",
+ "json-pointer",
+ "jsonpath",
+ "protocol"
]
},
{
diff --git a/apps/site/src/playgrounds/InterfaceWorkbench.playground.tsx b/apps/site/src/playgrounds/InterfaceWorkbench.playground.tsx
index da880b9c..1ba675a2 100644
--- a/apps/site/src/playgrounds/InterfaceWorkbench.playground.tsx
+++ b/apps/site/src/playgrounds/InterfaceWorkbench.playground.tsx
@@ -22,7 +22,7 @@ import {
type JSONCapabilityResult,
type Pointer,
type SelectionSnap,
-} from "@interactive-os/json-document";
+} from "@interactive-os/json-document/session";
import { useJSONDocument } from "@interactive-os/json-document/react";
const Card = z.object({
diff --git a/apps/site/src/routes/Home.tsx b/apps/site/src/routes/Home.tsx
index b49d37fb..68f24c25 100644
--- a/apps/site/src/routes/Home.tsx
+++ b/apps/site/src/routes/Home.tsx
@@ -1,9 +1,9 @@
const modelRows = [
- ["document", "value, patch, duplicate, read/query"],
- ["selection", "anchor, focus, ranges, text plans"],
- ["clipboard", "copy, cut, paste, payload insertion"],
- ["history", "undo, redo, transaction metadata"],
- ["can*", "reasoned checks for UI and tests"],
+ ["protocol", "provider-neutral JSON Patch application"],
+ ["projection", "value, at, query, canPatch, commit, subscribe"],
+ ["acceptance", "optional provider-neutral candidate validation"],
+ ["session", "optional selection, clipboard, history, rich edit verbs"],
+ ["host", "rendering, focus, keyboard, persistence, collaboration"],
] as const;
const BASE_PATH = import.meta.env.BASE_URL.replace(/\/$/, "");
@@ -19,14 +19,14 @@ export function Home() {
- Zod-guarded JSON editing
+ Provider-neutral JSON editing
json-document
- A headless document facade for JSON Patch, JSON Pointer, JSONPath,
- selection, clipboard, history, and reasoned capability checks.
+ A headless JSON protocol and six-member document projection for
+ documents, tables, slides, canvases, and notes.
@@ -49,7 +49,7 @@ export function Home() {
Install
-
npm install @interactive-os/json-document zod
+
npm install @interactive-os/json-document@2.0.0-rc.0
Start
{`import { createJSONDocument } from "@interactive-os/json-document";`}
@@ -82,8 +82,8 @@ export function Home() {