sheetnext 0.2.2 → 0.2.4

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.
@@ -1,426 +1,426 @@
1
- # SheetNext JSON Format
2
-
3
- > Manual supplemental document. This file is not generated by `scripts/doc-scanner.js`.
4
-
5
- ## Purpose
6
-
7
- `SN.IO.getData()` exports the current workbook into a JSON object.
8
-
9
- `SN.IO.setData(data)` restores a workbook from the same structure.
10
-
11
- This document describes the transport format used by those two APIs.
12
-
13
- ## Versioning
14
-
15
- - Current version: `2.0`
16
- - `setData` requires:
17
- - `data.version === "2.0"`
18
- - `data.sheets` to be a non-empty array
19
-
20
- If either check fails, `setData` returns `false`.
21
-
22
- ## Top-Level Shape
23
-
24
- ```json
25
- {
26
- "version": "2.0",
27
- "workbookName": "Book1",
28
- "activeSheet": "Sheet1",
29
- "calcMode": "auto",
30
- "readOnly": false,
31
- "properties": {},
32
- "definedNames": {},
33
- "styleTable": {
34
- "fonts": [],
35
- "fills": [],
36
- "borders": [],
37
- "aligns": [],
38
- "styles": []
39
- },
40
- "sizeTable": {
41
- "rowHeights": [],
42
- "colWidths": []
43
- },
44
- "sheets": []
45
- }
46
- ```
47
-
48
- ## Top-Level Fields
49
-
50
- | Field | Type | Required | Notes |
51
- | --- | --- | --- | --- |
52
- | `version` | string | Yes | Must currently be `"2.0"` |
53
- | `workbookName` | string | No | Workbook display name |
54
- | `activeSheet` | string \| null | No | Active sheet name to restore |
55
- | `calcMode` | `"auto"` \| `"manual"` | No | Defaults to `auto` on import |
56
- | `readOnly` | boolean | No | Workbook read-only state |
57
- | `properties` | object | No | Workbook custom properties |
58
- | `definedNames` | object | No | Workbook-level defined names |
59
- | `styleTable` | object | Yes | Deduplicated shared style pools |
60
- | `sizeTable` | object | Yes | Deduplicated row/column size pools |
61
- | `sheets` | array | Yes | Workbook sheet list |
62
- | `pivotCaches` | array | No | Pivot cache payloads |
63
- | `slicerCaches` | array | No | Slicer cache payloads |
64
- | `_snTrace` | any | No | Internal/export trace marker |
65
-
66
- ## Shared Tables
67
-
68
- `styleTable` and `sizeTable` are shared lookup tables.
69
-
70
- Instead of storing the same style or size object repeatedly on every cell/row/column, SheetNext stores the object once in a table and references it by index.
71
-
72
- ### `styleTable`
73
-
74
- | Field | Type | Used By |
75
- | --- | --- | --- |
76
- | `fonts` | array | cell `fo` |
77
- | `fills` | array | cell `fi` |
78
- | `borders` | array | cell `b` |
79
- | `aligns` | array | cell `a` |
80
- | `styles` | array | row `s`, column `s`, cell `s` |
81
-
82
- ### `sizeTable`
83
-
84
- | Field | Type | Used By |
85
- | --- | --- | --- |
86
- | `rowHeights` | array<number> | row `h` |
87
- | `colWidths` | array<number> | column `w` |
88
-
89
- ## Sheet Shape
90
-
91
- Each item in `sheets` looks like this:
92
-
93
- ```json
94
- {
95
- "name": "Sheet1",
96
- "hidden": false,
97
- "showGridLines": true,
98
- "showRowColHeaders": true,
99
- "showPageBreaks": false,
100
- "outlinePr": {},
101
- "frozenCols": 0,
102
- "frozenRows": 0,
103
- "freezeStartRow": 0,
104
- "freezeStartCol": 0,
105
- "defaultColWidth": 72,
106
- "defaultRowHeight": 21,
107
- "zoom": 1,
108
- "activeCell": { "r": 0, "c": 0 },
109
- "viewStart": { "r": 0, "c": 0 },
110
- "printSettings": null,
111
- "rowCount": 200,
112
- "colCount": 32,
113
- "cols": [],
114
- "rows": [],
115
- "merges": [],
116
- "drawings": []
117
- }
118
- ```
119
-
120
- ### Common Sheet Fields
121
-
122
- | Field | Type | Notes |
123
- | --- | --- | --- |
124
- | `name` | string | Sheet name |
125
- | `hidden` | boolean | Hidden sheet state |
126
- | `showGridLines` | boolean | Gridline visibility |
127
- | `showRowColHeaders` | boolean | Row/column header visibility |
128
- | `showPageBreaks` | boolean | Page break visibility |
129
- | `outlinePr` | object | Outline options |
130
- | `frozenCols` | number | Frozen column count |
131
- | `frozenRows` | number | Frozen row count |
132
- | `freezeStartRow` | number | Freeze split start row |
133
- | `freezeStartCol` | number | Freeze split start column |
134
- | `defaultColWidth` | number | Default width in px |
135
- | `defaultRowHeight` | number | Default height in px |
136
- | `zoom` | number | Import is clamped to `0.1` to `4` |
137
- | `activeCell` | `{r,c}` | Active cell |
138
- | `viewStart` | `{r,c}` | View origin |
139
- | `printSettings` | object \| null | Print config |
140
- | `rowCount` | number | Sheet size hint |
141
- | `colCount` | number | Sheet size hint |
142
- | `sheetProtection` | object | Optional sheet protection config |
143
-
144
- ### Optional Sheet Sections
145
-
146
- These sections are included only when data exists:
147
-
148
- - `cols`
149
- - `rows`
150
- - `merges`
151
- - `drawings`
152
- - `sparklines`
153
- - `comments`
154
- - `tables`
155
- - `autoFilters`
156
- - `cfRules`
157
- - `pivotTables`
158
- - `slicers`
159
-
160
- ## Column Records
161
-
162
- ```json
163
- {
164
- "cIndex": 0,
165
- "w": 3,
166
- "hidden": false,
167
- "ol": 1,
168
- "cl": false,
169
- "s": 2
170
- }
171
- ```
172
-
173
- | Field | Type | Notes |
174
- | --- | --- | --- |
175
- | `cIndex` | number | Zero-based column index |
176
- | `w` | number | Index into `sizeTable.colWidths` |
177
- | `hidden` | boolean | Hidden column |
178
- | `ol` | number | Outline level |
179
- | `cl` | boolean | Collapsed state |
180
- | `s` | number | Index into `styleTable.styles` |
181
-
182
- ## Row Records
183
-
184
- ```json
185
- {
186
- "rIndex": 0,
187
- "h": 4,
188
- "hidden": false,
189
- "ol": 1,
190
- "cl": false,
191
- "s": 5,
192
- "cells": []
193
- }
194
- ```
195
-
196
- | Field | Type | Notes |
197
- | --- | --- | --- |
198
- | `rIndex` | number | Zero-based row index |
199
- | `h` | number | Index into `sizeTable.rowHeights` |
200
- | `hidden` | boolean | Hidden row |
201
- | `ol` | number | Outline level |
202
- | `cl` | boolean | Collapsed state |
203
- | `s` | number | Index into `styleTable.styles` |
204
- | `cells` | array | Cell payload list |
205
-
206
- ## Cell Records
207
-
208
- Cell payloads are stored inside `row.cells`.
209
-
210
- ```json
211
- {
212
- "c": 0,
213
- "v": "Hello",
214
- "vt": "string",
215
- "s": 1
216
- }
217
- ```
218
-
219
- ### Cell Position Fields
220
-
221
- | Field | Type | Notes |
222
- | --- | --- | --- |
223
- | `c` | number | Start column index |
224
- | `e` | number | Optional end column index for repeated identical cells |
225
-
226
- If `e` is present, the same decoded cell template is applied from `c` through `e` inclusive.
227
-
228
- ### Cell Value Fields
229
-
230
- | Field | Type | Notes |
231
- | --- | --- | --- |
232
- | `v` | any | Raw cell value |
233
- | `vt` | string \| null | Value type marker |
234
- | `f` | string | Formula string; importer ensures a leading `=` |
235
- | `cv` | any | Cached formula result |
236
- | `cvt` | string \| null | Cached result type marker |
237
-
238
- Supported type markers:
239
-
240
- - `date`
241
- - `time`
242
- - `dateTime`
243
- - `nan`
244
- - `inf`
245
- - `-inf`
246
-
247
- ### Cell Style Fields
248
-
249
- | Field | Type | Notes |
250
- | --- | --- | --- |
251
- | `s` | number | Index into `styleTable.styles` |
252
- | `fo` | number | Index into `styleTable.fonts` |
253
- | `fi` | number | Index into `styleTable.fills` |
254
- | `b` | number | Index into `styleTable.borders` |
255
- | `a` | number | Index into `styleTable.aligns` |
256
- | `fmt` | string | Number format |
257
- | `p` | object | Protection overrides |
258
-
259
- ### Cell Feature Fields
260
-
261
- | Field | Type | Notes |
262
- | --- | --- | --- |
263
- | `link` | object | Hyperlink payload |
264
- | `dv` | object | Data validation payload |
265
- | `rt` | array | Rich text runs |
266
-
267
- Hyperlink shape:
268
-
269
- ```json
270
- {
271
- "t": "https://example.com",
272
- "l": null,
273
- "tt": "Open link"
274
- }
275
- ```
276
-
277
- ## Merge Records
278
-
279
- Each merge item is a normalized range object:
280
-
281
- ```json
282
- {
283
- "s": { "r": 0, "c": 0 },
284
- "e": { "r": 1, "c": 2 }
285
- }
286
- ```
287
-
288
- ## Drawing Records
289
-
290
- Basic drawing shape:
291
-
292
- ```json
293
- {
294
- "type": "image",
295
- "startCell": { "r": 1, "c": 1 },
296
- "offsetX": 0,
297
- "offsetY": 0,
298
- "width": 240,
299
- "height": 120,
300
- "anchorType": "twoCell",
301
- "rotation": 0
302
- }
303
- ```
304
-
305
- Additional drawing fields depend on `type`:
306
-
307
- - `chart`: `chartOption`
308
- - `image`: `imageBase64`
309
- - `shape` / `connector`: `shapeType`, `shapeStyle`, `shapeText`, `isTextBox`
310
-
311
- ## Other Optional Sections
312
-
313
- Sheet-level optional payloads:
314
-
315
- - `sparklines`
316
- - `comments`
317
- - `tables`
318
- - `autoFilters`
319
- - `cfRules`
320
- - `pivotTables`
321
- - `slicers`
322
-
323
- Workbook-level optional payloads:
324
-
325
- - `pivotCaches`
326
- - `slicerCaches`
327
-
328
- These sections are round-tripped by `getData` / `setData`, but many of them are larger feature-specific payloads and are best produced by exporting an existing workbook first.
329
-
330
- ## Dynamic Value Wrapper
331
-
332
- Some advanced cache payloads use a typed wrapper so special values survive JSON serialization:
333
-
334
- ```json
335
- {
336
- "__sn_json_type": "date",
337
- "__sn_json_value": "2026-03-17T00:00:00.000Z"
338
- }
339
- ```
340
-
341
- Possible wrapper types:
342
-
343
- - `date`
344
- - `nan`
345
- - `inf`
346
- - `-inf`
347
-
348
- ## Minimal Example
349
-
350
- ```json
351
- {
352
- "version": "2.0",
353
- "workbookName": "Demo",
354
- "activeSheet": "Sheet1",
355
- "calcMode": "auto",
356
- "readOnly": false,
357
- "properties": {},
358
- "definedNames": {},
359
- "styleTable": {
360
- "fonts": [],
361
- "fills": [],
362
- "borders": [],
363
- "aligns": [],
364
- "styles": []
365
- },
366
- "sizeTable": {
367
- "rowHeights": [],
368
- "colWidths": []
369
- },
370
- "sheets": [
371
- {
372
- "name": "Sheet1",
373
- "hidden": false,
374
- "showGridLines": true,
375
- "showRowColHeaders": true,
376
- "showPageBreaks": false,
377
- "outlinePr": {},
378
- "frozenCols": 0,
379
- "frozenRows": 0,
380
- "freezeStartRow": 0,
381
- "freezeStartCol": 0,
382
- "defaultColWidth": 72,
383
- "defaultRowHeight": 21,
384
- "zoom": 1,
385
- "activeCell": { "r": 0, "c": 0 },
386
- "viewStart": { "r": 0, "c": 0 },
387
- "printSettings": null,
388
- "rowCount": 10,
389
- "colCount": 10,
390
- "cols": [],
391
- "rows": [
392
- {
393
- "rIndex": 0,
394
- "h": 0,
395
- "cells": [
396
- { "c": 0, "v": "Name" },
397
- { "c": 1, "v": "Score" }
398
- ]
399
- },
400
- {
401
- "rIndex": 1,
402
- "h": 0,
403
- "cells": [
404
- { "c": 0, "v": "Alice" },
405
- { "c": 1, "v": 95 }
406
- ]
407
- }
408
- ],
409
- "merges": [],
410
- "drawings": []
411
- }
412
- ]
413
- }
414
- ```
415
-
416
- ## Recommended Workflow
417
-
418
- If you need to generate JSON externally:
419
-
420
- 1. create a workbook in SheetNext
421
- 2. export it with `SN.IO.getData()`
422
- 3. treat that JSON as the baseline contract
423
- 4. modify only the sections you need
424
- 5. import it back with `SN.IO.setData(data)`
425
-
426
- This is the safest way to stay aligned with future feature additions.
1
+ # SheetNext JSON Format
2
+
3
+ > Manual supplemental document. This file is not generated by `scripts/doc-scanner.js`.
4
+
5
+ ## Purpose
6
+
7
+ `SN.IO.getData()` exports the current workbook into a JSON object.
8
+
9
+ `SN.IO.setData(data)` restores a workbook from the same structure.
10
+
11
+ This document describes the transport format used by those two APIs.
12
+
13
+ ## Versioning
14
+
15
+ - Current version: `2.0`
16
+ - `setData` requires:
17
+ - `data.version === "2.0"`
18
+ - `data.sheets` to be a non-empty array
19
+
20
+ If either check fails, `setData` returns `false`.
21
+
22
+ ## Top-Level Shape
23
+
24
+ ```json
25
+ {
26
+ "version": "2.0",
27
+ "workbookName": "Book1",
28
+ "activeSheet": "Sheet1",
29
+ "calcMode": "auto",
30
+ "readOnly": false,
31
+ "properties": {},
32
+ "definedNames": {},
33
+ "styleTable": {
34
+ "fonts": [],
35
+ "fills": [],
36
+ "borders": [],
37
+ "aligns": [],
38
+ "styles": []
39
+ },
40
+ "sizeTable": {
41
+ "rowHeights": [],
42
+ "colWidths": []
43
+ },
44
+ "sheets": []
45
+ }
46
+ ```
47
+
48
+ ## Top-Level Fields
49
+
50
+ | Field | Type | Required | Notes |
51
+ | --- | --- | --- | --- |
52
+ | `version` | string | Yes | Must currently be `"2.0"` |
53
+ | `workbookName` | string | No | Workbook display name |
54
+ | `activeSheet` | string \| null | No | Active sheet name to restore |
55
+ | `calcMode` | `"auto"` \| `"manual"` | No | Defaults to `auto` on import |
56
+ | `readOnly` | boolean | No | Workbook read-only state |
57
+ | `properties` | object | No | Workbook custom properties |
58
+ | `definedNames` | object | No | Workbook-level defined names |
59
+ | `styleTable` | object | Yes | Deduplicated shared style pools |
60
+ | `sizeTable` | object | Yes | Deduplicated row/column size pools |
61
+ | `sheets` | array | Yes | Workbook sheet list |
62
+ | `pivotCaches` | array | No | Pivot cache payloads |
63
+ | `slicerCaches` | array | No | Slicer cache payloads |
64
+ | `_snTrace` | any | No | Internal/export trace marker |
65
+
66
+ ## Shared Tables
67
+
68
+ `styleTable` and `sizeTable` are shared lookup tables.
69
+
70
+ Instead of storing the same style or size object repeatedly on every cell/row/column, SheetNext stores the object once in a table and references it by index.
71
+
72
+ ### `styleTable`
73
+
74
+ | Field | Type | Used By |
75
+ | --- | --- | --- |
76
+ | `fonts` | array | cell `fo` |
77
+ | `fills` | array | cell `fi` |
78
+ | `borders` | array | cell `b` |
79
+ | `aligns` | array | cell `a` |
80
+ | `styles` | array | row `s`, column `s`, cell `s` |
81
+
82
+ ### `sizeTable`
83
+
84
+ | Field | Type | Used By |
85
+ | --- | --- | --- |
86
+ | `rowHeights` | array<number> | row `h` |
87
+ | `colWidths` | array<number> | column `w` |
88
+
89
+ ## Sheet Shape
90
+
91
+ Each item in `sheets` looks like this:
92
+
93
+ ```json
94
+ {
95
+ "name": "Sheet1",
96
+ "hidden": false,
97
+ "showGridLines": true,
98
+ "showRowColHeaders": true,
99
+ "showPageBreaks": false,
100
+ "outlinePr": {},
101
+ "frozenCols": 0,
102
+ "frozenRows": 0,
103
+ "freezeStartRow": 0,
104
+ "freezeStartCol": 0,
105
+ "defaultColWidth": 72,
106
+ "defaultRowHeight": 21,
107
+ "zoom": 1,
108
+ "activeCell": { "r": 0, "c": 0 },
109
+ "viewStart": { "r": 0, "c": 0 },
110
+ "printSettings": null,
111
+ "rowCount": 200,
112
+ "colCount": 32,
113
+ "cols": [],
114
+ "rows": [],
115
+ "merges": [],
116
+ "drawings": []
117
+ }
118
+ ```
119
+
120
+ ### Common Sheet Fields
121
+
122
+ | Field | Type | Notes |
123
+ | --- | --- | --- |
124
+ | `name` | string | Sheet name |
125
+ | `hidden` | boolean | Hidden sheet state |
126
+ | `showGridLines` | boolean | Gridline visibility |
127
+ | `showRowColHeaders` | boolean | Row/column header visibility |
128
+ | `showPageBreaks` | boolean | Page break visibility |
129
+ | `outlinePr` | object | Outline options |
130
+ | `frozenCols` | number | Frozen column count |
131
+ | `frozenRows` | number | Frozen row count |
132
+ | `freezeStartRow` | number | Freeze split start row |
133
+ | `freezeStartCol` | number | Freeze split start column |
134
+ | `defaultColWidth` | number | Default width in px |
135
+ | `defaultRowHeight` | number | Default height in px |
136
+ | `zoom` | number | Import is clamped to `0.1` to `4` |
137
+ | `activeCell` | `{r,c}` | Active cell |
138
+ | `viewStart` | `{r,c}` | View origin |
139
+ | `printSettings` | object \| null | Print config |
140
+ | `rowCount` | number | Sheet size hint |
141
+ | `colCount` | number | Sheet size hint |
142
+ | `sheetProtection` | object | Optional sheet protection config |
143
+
144
+ ### Optional Sheet Sections
145
+
146
+ These sections are included only when data exists:
147
+
148
+ - `cols`
149
+ - `rows`
150
+ - `merges`
151
+ - `drawings`
152
+ - `sparklines`
153
+ - `comments`
154
+ - `tables`
155
+ - `autoFilters`
156
+ - `cfRules`
157
+ - `pivotTables`
158
+ - `slicers`
159
+
160
+ ## Column Records
161
+
162
+ ```json
163
+ {
164
+ "cIndex": 0,
165
+ "w": 3,
166
+ "hidden": false,
167
+ "ol": 1,
168
+ "cl": false,
169
+ "s": 2
170
+ }
171
+ ```
172
+
173
+ | Field | Type | Notes |
174
+ | --- | --- | --- |
175
+ | `cIndex` | number | Zero-based column index |
176
+ | `w` | number | Index into `sizeTable.colWidths` |
177
+ | `hidden` | boolean | Hidden column |
178
+ | `ol` | number | Outline level |
179
+ | `cl` | boolean | Collapsed state |
180
+ | `s` | number | Index into `styleTable.styles` |
181
+
182
+ ## Row Records
183
+
184
+ ```json
185
+ {
186
+ "rIndex": 0,
187
+ "h": 4,
188
+ "hidden": false,
189
+ "ol": 1,
190
+ "cl": false,
191
+ "s": 5,
192
+ "cells": []
193
+ }
194
+ ```
195
+
196
+ | Field | Type | Notes |
197
+ | --- | --- | --- |
198
+ | `rIndex` | number | Zero-based row index |
199
+ | `h` | number | Index into `sizeTable.rowHeights` |
200
+ | `hidden` | boolean | Hidden row |
201
+ | `ol` | number | Outline level |
202
+ | `cl` | boolean | Collapsed state |
203
+ | `s` | number | Index into `styleTable.styles` |
204
+ | `cells` | array | Cell payload list |
205
+
206
+ ## Cell Records
207
+
208
+ Cell payloads are stored inside `row.cells`.
209
+
210
+ ```json
211
+ {
212
+ "c": 0,
213
+ "v": "Hello",
214
+ "vt": "string",
215
+ "s": 1
216
+ }
217
+ ```
218
+
219
+ ### Cell Position Fields
220
+
221
+ | Field | Type | Notes |
222
+ | --- | --- | --- |
223
+ | `c` | number | Start column index |
224
+ | `e` | number | Optional end column index for repeated identical cells |
225
+
226
+ If `e` is present, the same decoded cell template is applied from `c` through `e` inclusive.
227
+
228
+ ### Cell Value Fields
229
+
230
+ | Field | Type | Notes |
231
+ | --- | --- | --- |
232
+ | `v` | any | Raw cell value |
233
+ | `vt` | string \| null | Value type marker |
234
+ | `f` | string | Formula string; importer ensures a leading `=` |
235
+ | `cv` | any | Cached formula result |
236
+ | `cvt` | string \| null | Cached result type marker |
237
+
238
+ Supported type markers:
239
+
240
+ - `date`
241
+ - `time`
242
+ - `dateTime`
243
+ - `nan`
244
+ - `inf`
245
+ - `-inf`
246
+
247
+ ### Cell Style Fields
248
+
249
+ | Field | Type | Notes |
250
+ | --- | --- | --- |
251
+ | `s` | number | Index into `styleTable.styles` |
252
+ | `fo` | number | Index into `styleTable.fonts` |
253
+ | `fi` | number | Index into `styleTable.fills` |
254
+ | `b` | number | Index into `styleTable.borders` |
255
+ | `a` | number | Index into `styleTable.aligns` |
256
+ | `fmt` | string | Number format |
257
+ | `p` | object | Protection overrides |
258
+
259
+ ### Cell Feature Fields
260
+
261
+ | Field | Type | Notes |
262
+ | --- | --- | --- |
263
+ | `link` | object | Hyperlink payload |
264
+ | `dv` | object | Data validation payload |
265
+ | `rt` | array | Rich text runs |
266
+
267
+ Hyperlink shape:
268
+
269
+ ```json
270
+ {
271
+ "t": "https://example.com",
272
+ "l": null,
273
+ "tt": "Open link"
274
+ }
275
+ ```
276
+
277
+ ## Merge Records
278
+
279
+ Each merge item is a normalized range object:
280
+
281
+ ```json
282
+ {
283
+ "s": { "r": 0, "c": 0 },
284
+ "e": { "r": 1, "c": 2 }
285
+ }
286
+ ```
287
+
288
+ ## Drawing Records
289
+
290
+ Basic drawing shape:
291
+
292
+ ```json
293
+ {
294
+ "type": "image",
295
+ "startCell": { "r": 1, "c": 1 },
296
+ "offsetX": 0,
297
+ "offsetY": 0,
298
+ "width": 240,
299
+ "height": 120,
300
+ "anchorType": "twoCell",
301
+ "rotation": 0
302
+ }
303
+ ```
304
+
305
+ Additional drawing fields depend on `type`:
306
+
307
+ - `chart`: `chartOption`
308
+ - `image`: `imageBase64`
309
+ - `shape` / `connector`: `shapeType`, `shapeStyle`, `shapeText`, `isTextBox`
310
+
311
+ ## Other Optional Sections
312
+
313
+ Sheet-level optional payloads:
314
+
315
+ - `sparklines`
316
+ - `comments`
317
+ - `tables`
318
+ - `autoFilters`
319
+ - `cfRules`
320
+ - `pivotTables`
321
+ - `slicers`
322
+
323
+ Workbook-level optional payloads:
324
+
325
+ - `pivotCaches`
326
+ - `slicerCaches`
327
+
328
+ These sections are round-tripped by `getData` / `setData`, but many of them are larger feature-specific payloads and are best produced by exporting an existing workbook first.
329
+
330
+ ## Dynamic Value Wrapper
331
+
332
+ Some advanced cache payloads use a typed wrapper so special values survive JSON serialization:
333
+
334
+ ```json
335
+ {
336
+ "__sn_json_type": "date",
337
+ "__sn_json_value": "2026-03-17T00:00:00.000Z"
338
+ }
339
+ ```
340
+
341
+ Possible wrapper types:
342
+
343
+ - `date`
344
+ - `nan`
345
+ - `inf`
346
+ - `-inf`
347
+
348
+ ## Minimal Example
349
+
350
+ ```json
351
+ {
352
+ "version": "2.0",
353
+ "workbookName": "Demo",
354
+ "activeSheet": "Sheet1",
355
+ "calcMode": "auto",
356
+ "readOnly": false,
357
+ "properties": {},
358
+ "definedNames": {},
359
+ "styleTable": {
360
+ "fonts": [],
361
+ "fills": [],
362
+ "borders": [],
363
+ "aligns": [],
364
+ "styles": []
365
+ },
366
+ "sizeTable": {
367
+ "rowHeights": [],
368
+ "colWidths": []
369
+ },
370
+ "sheets": [
371
+ {
372
+ "name": "Sheet1",
373
+ "hidden": false,
374
+ "showGridLines": true,
375
+ "showRowColHeaders": true,
376
+ "showPageBreaks": false,
377
+ "outlinePr": {},
378
+ "frozenCols": 0,
379
+ "frozenRows": 0,
380
+ "freezeStartRow": 0,
381
+ "freezeStartCol": 0,
382
+ "defaultColWidth": 72,
383
+ "defaultRowHeight": 21,
384
+ "zoom": 1,
385
+ "activeCell": { "r": 0, "c": 0 },
386
+ "viewStart": { "r": 0, "c": 0 },
387
+ "printSettings": null,
388
+ "rowCount": 10,
389
+ "colCount": 10,
390
+ "cols": [],
391
+ "rows": [
392
+ {
393
+ "rIndex": 0,
394
+ "h": 0,
395
+ "cells": [
396
+ { "c": 0, "v": "Name" },
397
+ { "c": 1, "v": "Score" }
398
+ ]
399
+ },
400
+ {
401
+ "rIndex": 1,
402
+ "h": 0,
403
+ "cells": [
404
+ { "c": 0, "v": "Alice" },
405
+ { "c": 1, "v": 95 }
406
+ ]
407
+ }
408
+ ],
409
+ "merges": [],
410
+ "drawings": []
411
+ }
412
+ ]
413
+ }
414
+ ```
415
+
416
+ ## Recommended Workflow
417
+
418
+ If you need to generate JSON externally:
419
+
420
+ 1. create a workbook in SheetNext
421
+ 2. export it with `SN.IO.getData()`
422
+ 3. treat that JSON as the baseline contract
423
+ 4. modify only the sections you need
424
+ 5. import it back with `SN.IO.setData(data)`
425
+
426
+ This is the safest way to stay aligned with future feature additions.