Skip to content

Commit 41dea37

Browse files
authored
feat(document-api): history name space (#2219)
* feat(document-api): history name space * chore: fix sdk validation
1 parent 32c9991 commit 41dea37

38 files changed

Lines changed: 1631 additions & 43 deletions

apps/cli/scripts/export-sdk-contract.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -172,6 +172,9 @@ const INTENT_NAMES = {
172172
'doc.tables.get': 'get_table',
173173
'doc.tables.getCells': 'get_table_cells',
174174
'doc.tables.getProperties': 'get_table_properties',
175+
'doc.history.get': 'get_history',
176+
'doc.history.undo': 'undo',
177+
'doc.history.redo': 'redo',
175178
} as const satisfies Record<DocBackedCliOpId, string>;
176179

177180
// ---------------------------------------------------------------------------

apps/cli/src/__tests__/conformance/scenarios.ts

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1553,6 +1553,26 @@ export const SUCCESS_SCENARIOS = {
15531553
'doc.tables.get': tableReadScenario('tables.get'),
15541554
'doc.tables.getCells': tableReadScenario('tables.getCells'),
15551555
'doc.tables.getProperties': tableReadScenario('tables.getProperties'),
1556+
1557+
// ---------------------------------------------------------------------------
1558+
// History operations
1559+
// ---------------------------------------------------------------------------
1560+
1561+
'doc.history.get': async (harness: ConformanceHarness): Promise<ScenarioInvocation> => {
1562+
const stateDir = await harness.createStateDir('doc-history-get-success');
1563+
await harness.openSessionFixture(stateDir, 'doc-history-get', 'history-get-session');
1564+
return { stateDir, args: ['history', 'get', '--session', 'history-get-session'] };
1565+
},
1566+
'doc.history.undo': async (harness: ConformanceHarness): Promise<ScenarioInvocation> => {
1567+
const stateDir = await harness.createStateDir('doc-history-undo-success');
1568+
await harness.openSessionFixture(stateDir, 'doc-history-undo', 'history-undo-session');
1569+
return { stateDir, args: ['history', 'undo', '--session', 'history-undo-session'] };
1570+
},
1571+
'doc.history.redo': async (harness: ConformanceHarness): Promise<ScenarioInvocation> => {
1572+
const stateDir = await harness.createStateDir('doc-history-redo-success');
1573+
await harness.openSessionFixture(stateDir, 'doc-history-redo', 'history-redo-session');
1574+
return { stateDir, args: ['history', 'redo', '--session', 'history-redo-session'] };
1575+
},
15561576
} as const satisfies Record<CliOperationId, (harness: ConformanceHarness) => Promise<ScenarioInvocation>>;
15571577

15581578
export const OPERATION_SCENARIOS = (Object.keys(SUCCESS_SCENARIOS) as CliOperationId[]).map((operationId) => {

apps/cli/src/__tests__/contract-response-conformance.test.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,14 @@ describe('contract response conformance', () => {
3535

3636
const success = envelope as SuccessEnvelope;
3737
validateOperationResponseData(scenario.operationId, success.data, commandKey);
38+
39+
// Regression guard: history operations must serialize payload under `result`,
40+
// never under an "undefined" key from missing envelope metadata.
41+
if (scenario.operationId.startsWith('doc.history.')) {
42+
const data = success.data as Record<string, unknown>;
43+
expect(Object.prototype.hasOwnProperty.call(data, 'result')).toBe(true);
44+
expect(Object.prototype.hasOwnProperty.call(data, 'undefined')).toBe(false);
45+
}
3846
});
3947

4048
test(`failure envelope conforms for ${scenario.operationId}`, async () => {

apps/cli/src/cli/operation-hints.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,9 @@ export const SUCCESS_VERB: Record<CliExposedOperationId, string> = {
154154
'tables.get': 'resolved table',
155155
'tables.getCells': 'listed cells',
156156
'tables.getProperties': 'resolved table properties',
157+
'history.get': 'retrieved history state',
158+
'history.undo': 'undid last change',
159+
'history.redo': 'redid last change',
157160
};
158161

159162
// ---------------------------------------------------------------------------
@@ -267,6 +270,9 @@ export const OUTPUT_FORMAT: Record<CliExposedOperationId, OutputFormat> = {
267270
'tables.get': 'tableInfo',
268271
'tables.getCells': 'tableCellList',
269272
'tables.getProperties': 'tablePropertiesInfo',
273+
'history.get': 'plain',
274+
'history.undo': 'plain',
275+
'history.redo': 'plain',
270276
};
271277

272278
// ---------------------------------------------------------------------------
@@ -364,6 +370,9 @@ export const RESPONSE_ENVELOPE_KEY: Record<CliExposedOperationId, string | null>
364370
'tables.get': 'result',
365371
'tables.getCells': 'result',
366372
'tables.getProperties': 'result',
373+
'history.get': 'result',
374+
'history.undo': 'result',
375+
'history.redo': 'result',
367376
};
368377

369378
// ---------------------------------------------------------------------------
@@ -489,4 +498,7 @@ export const OPERATION_FAMILY: Record<CliExposedOperationId, OperationFamily> =
489498
'tables.get': 'tables',
490499
'tables.getCells': 'tables',
491500
'tables.getProperties': 'tables',
501+
'history.get': 'query',
502+
'history.undo': 'general',
503+
'history.redo': 'general',
492504
};

apps/cli/src/cli/types.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,7 @@ export type CliCategory =
124124
| 'comments'
125125
| 'trackChanges'
126126
| 'capabilities'
127+
| 'history'
127128
| 'lifecycle'
128129
| 'session'
129130
| 'introspection';

apps/docs/document-api/available-operations.mdx

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ Use the tables below to see what operations are available and where each one is
2020
| Core | 8 | 0 | 8 | [Reference](/document-api/reference/core/index) |
2121
| Create | 5 | 0 | 5 | [Reference](/document-api/reference/create/index) |
2222
| Format | 44 | 1 | 45 | [Reference](/document-api/reference/format/index) |
23+
| History | 3 | 0 | 3 | [Reference](/document-api/reference/history/index) |
2324
| Lists | 8 | 0 | 8 | [Reference](/document-api/reference/lists/index) |
2425
| Mutations | 2 | 0 | 2 | [Reference](/document-api/reference/mutations/index) |
2526
| Paragraph Formatting | 17 | 0 | 17 | [Reference](/document-api/reference/format/paragraph/index) |
@@ -98,6 +99,9 @@ Use the tables below to see what operations are available and where each one is
9899
| <span style={{ whiteSpace: 'nowrap', wordBreak: 'normal', overflowWrap: 'normal' }}><code>editor.doc.format.stylisticSets(...)</code></span> | [`format.stylisticSets`](/document-api/reference/format/stylistic-sets) |
99100
| <span style={{ whiteSpace: 'nowrap', wordBreak: 'normal', overflowWrap: 'normal' }}><code>editor.doc.format.contextualAlternates(...)</code></span> | [`format.contextualAlternates`](/document-api/reference/format/contextual-alternates) |
100101
| <span style={{ whiteSpace: 'nowrap', wordBreak: 'normal', overflowWrap: 'normal' }}><code>editor.doc.format.strikethrough(...)</code></span> | [`format.strike`](/document-api/reference/format/strike) |
102+
| <span style={{ whiteSpace: 'nowrap', wordBreak: 'normal', overflowWrap: 'normal' }}><code>editor.doc.history.get(...)</code></span> | [`history.get`](/document-api/reference/history/get) |
103+
| <span style={{ whiteSpace: 'nowrap', wordBreak: 'normal', overflowWrap: 'normal' }}><code>editor.doc.history.undo(...)</code></span> | [`history.undo`](/document-api/reference/history/undo) |
104+
| <span style={{ whiteSpace: 'nowrap', wordBreak: 'normal', overflowWrap: 'normal' }}><code>editor.doc.history.redo(...)</code></span> | [`history.redo`](/document-api/reference/history/redo) |
101105
| <span style={{ whiteSpace: 'nowrap', wordBreak: 'normal', overflowWrap: 'normal' }}><code>editor.doc.lists.list(...)</code></span> | [`lists.list`](/document-api/reference/lists/list) |
102106
| <span style={{ whiteSpace: 'nowrap', wordBreak: 'normal', overflowWrap: 'normal' }}><code>editor.doc.lists.get(...)</code></span> | [`lists.get`](/document-api/reference/lists/get) |
103107
| <span style={{ whiteSpace: 'nowrap', wordBreak: 'normal', overflowWrap: 'normal' }}><code>editor.doc.lists.insert(...)</code></span> | [`lists.insert`](/document-api/reference/lists/insert) |

apps/docs/document-api/reference/_generated-manifest.json

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,10 @@
8686
"apps/docs/document-api/reference/get-node-by-id.mdx",
8787
"apps/docs/document-api/reference/get-node.mdx",
8888
"apps/docs/document-api/reference/get-text.mdx",
89+
"apps/docs/document-api/reference/history/get.mdx",
90+
"apps/docs/document-api/reference/history/index.mdx",
91+
"apps/docs/document-api/reference/history/redo.mdx",
92+
"apps/docs/document-api/reference/history/undo.mdx",
8993
"apps/docs/document-api/reference/index.mdx",
9094
"apps/docs/document-api/reference/info.mdx",
9195
"apps/docs/document-api/reference/insert.mdx",
@@ -423,6 +427,13 @@
423427
"pagePath": "apps/docs/document-api/reference/tables/index.mdx",
424428
"title": "Tables"
425429
},
430+
{
431+
"aliasMemberPaths": [],
432+
"key": "history",
433+
"operationIds": ["history.get", "history.undo", "history.redo"],
434+
"pagePath": "apps/docs/document-api/reference/history/index.mdx",
435+
"title": "History"
436+
},
426437
{
427438
"aliasMemberPaths": [],
428439
"key": "toc",
@@ -432,5 +443,5 @@
432443
}
433444
],
434445
"marker": "{/* GENERATED FILE: DO NOT EDIT. Regenerate via `pnpm run docapi:sync`. */}",
435-
"sourceHash": "98ac639d0837d66b0d968f4a0811a0bac22f407a989caeda784326e40f337e68"
446+
"sourceHash": "c5cf08d833b08c281a2bb18ec03caa6d95d20f69defe7897b30a9b903774705c"
436447
}

apps/docs/document-api/reference/capabilities/get.mdx

Lines changed: 168 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -322,6 +322,12 @@ _No fields._
322322
"COMMAND_UNAVAILABLE"
323323
]
324324
},
325+
"history": {
326+
"enabled": true,
327+
"reasons": [
328+
"COMMAND_UNAVAILABLE"
329+
]
330+
},
325331
"lists": {
326332
"enabled": true,
327333
"reasons": [
@@ -960,6 +966,30 @@ _No fields._
960966
],
961967
"tracked": true
962968
},
969+
"history.get": {
970+
"available": true,
971+
"dryRun": true,
972+
"reasons": [
973+
"COMMAND_UNAVAILABLE"
974+
],
975+
"tracked": true
976+
},
977+
"history.redo": {
978+
"available": true,
979+
"dryRun": true,
980+
"reasons": [
981+
"COMMAND_UNAVAILABLE"
982+
],
983+
"tracked": true
984+
},
985+
"history.undo": {
986+
"available": true,
987+
"dryRun": true,
988+
"reasons": [
989+
"COMMAND_UNAVAILABLE"
990+
],
991+
"tracked": true
992+
},
963993
"info": {
964994
"available": true,
965995
"dryRun": true,
@@ -3195,6 +3225,33 @@ _No fields._
31953225
],
31963226
"type": "object"
31973227
},
3228+
"history": {
3229+
"additionalProperties": false,
3230+
"properties": {
3231+
"enabled": {
3232+
"type": "boolean"
3233+
},
3234+
"reasons": {
3235+
"items": {
3236+
"enum": [
3237+
"COMMAND_UNAVAILABLE",
3238+
"HELPER_UNAVAILABLE",
3239+
"OPERATION_UNAVAILABLE",
3240+
"TRACKED_MODE_UNAVAILABLE",
3241+
"DRY_RUN_UNAVAILABLE",
3242+
"NAMESPACE_UNAVAILABLE",
3243+
"STYLES_PART_MISSING",
3244+
"COLLABORATION_ACTIVE"
3245+
]
3246+
},
3247+
"type": "array"
3248+
}
3249+
},
3250+
"required": [
3251+
"enabled"
3252+
],
3253+
"type": "object"
3254+
},
31983255
"lists": {
31993256
"additionalProperties": false,
32003257
"properties": {
@@ -3254,7 +3311,8 @@ _No fields._
32543311
"trackChanges",
32553312
"comments",
32563313
"lists",
3257-
"dryRun"
3314+
"dryRun",
3315+
"history"
32583316
],
32593317
"type": "object"
32603318
},
@@ -5991,6 +6049,111 @@ _No fields._
59916049
],
59926050
"type": "object"
59936051
},
6052+
"history.get": {
6053+
"additionalProperties": false,
6054+
"properties": {
6055+
"available": {
6056+
"type": "boolean"
6057+
},
6058+
"dryRun": {
6059+
"type": "boolean"
6060+
},
6061+
"reasons": {
6062+
"items": {
6063+
"enum": [
6064+
"COMMAND_UNAVAILABLE",
6065+
"HELPER_UNAVAILABLE",
6066+
"OPERATION_UNAVAILABLE",
6067+
"TRACKED_MODE_UNAVAILABLE",
6068+
"DRY_RUN_UNAVAILABLE",
6069+
"NAMESPACE_UNAVAILABLE",
6070+
"STYLES_PART_MISSING",
6071+
"COLLABORATION_ACTIVE"
6072+
]
6073+
},
6074+
"type": "array"
6075+
},
6076+
"tracked": {
6077+
"type": "boolean"
6078+
}
6079+
},
6080+
"required": [
6081+
"available",
6082+
"tracked",
6083+
"dryRun"
6084+
],
6085+
"type": "object"
6086+
},
6087+
"history.redo": {
6088+
"additionalProperties": false,
6089+
"properties": {
6090+
"available": {
6091+
"type": "boolean"
6092+
},
6093+
"dryRun": {
6094+
"type": "boolean"
6095+
},
6096+
"reasons": {
6097+
"items": {
6098+
"enum": [
6099+
"COMMAND_UNAVAILABLE",
6100+
"HELPER_UNAVAILABLE",
6101+
"OPERATION_UNAVAILABLE",
6102+
"TRACKED_MODE_UNAVAILABLE",
6103+
"DRY_RUN_UNAVAILABLE",
6104+
"NAMESPACE_UNAVAILABLE",
6105+
"STYLES_PART_MISSING",
6106+
"COLLABORATION_ACTIVE"
6107+
]
6108+
},
6109+
"type": "array"
6110+
},
6111+
"tracked": {
6112+
"type": "boolean"
6113+
}
6114+
},
6115+
"required": [
6116+
"available",
6117+
"tracked",
6118+
"dryRun"
6119+
],
6120+
"type": "object"
6121+
},
6122+
"history.undo": {
6123+
"additionalProperties": false,
6124+
"properties": {
6125+
"available": {
6126+
"type": "boolean"
6127+
},
6128+
"dryRun": {
6129+
"type": "boolean"
6130+
},
6131+
"reasons": {
6132+
"items": {
6133+
"enum": [
6134+
"COMMAND_UNAVAILABLE",
6135+
"HELPER_UNAVAILABLE",
6136+
"OPERATION_UNAVAILABLE",
6137+
"TRACKED_MODE_UNAVAILABLE",
6138+
"DRY_RUN_UNAVAILABLE",
6139+
"NAMESPACE_UNAVAILABLE",
6140+
"STYLES_PART_MISSING",
6141+
"COLLABORATION_ACTIVE"
6142+
]
6143+
},
6144+
"type": "array"
6145+
},
6146+
"tracked": {
6147+
"type": "boolean"
6148+
}
6149+
},
6150+
"required": [
6151+
"available",
6152+
"tracked",
6153+
"dryRun"
6154+
],
6155+
"type": "object"
6156+
},
59946157
"info": {
59956158
"additionalProperties": false,
59966159
"properties": {
@@ -9022,7 +9185,10 @@ _No fields._
90229185
"toc.get",
90239186
"toc.configure",
90249187
"toc.update",
9025-
"toc.remove"
9188+
"toc.remove",
9189+
"history.get",
9190+
"history.undo",
9191+
"history.redo"
90269192
],
90279193
"type": "object"
90289194
},

0 commit comments

Comments
 (0)