@textmode/document 1.0.0 → 1.1.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/README.md CHANGED
@@ -4,18 +4,18 @@
4
4
 
5
5
  <img alt="@textmode/document, portable textmode documents" src=".github/assets/readme-og.png" />
6
6
 
7
- | [![Node.js 24](https://img.shields.io/badge/Node.js-24-339933?logo=nodedotjs&logoColor=white)](https://nodejs.org/) [![TypeScript](https://img.shields.io/badge/TypeScript-3178C6?logo=typescript&logoColor=white)](https://www.typescriptlang.org/) [![JSON Schema Draft 2020-12](https://img.shields.io/badge/JSON_Schema-Draft_2020--12-85EA2D?logo=json&logoColor=white)](https://json-schema.org/draft/2020-12) | [![docs](https://img.shields.io/badge/docs-vitepress-646cff?logo=vitepress&logoColor=white)](https://code.textmode.art/) [![Discord](https://img.shields.io/discord/1357070706181017691?color=5865F2&label=Discord&logo=discord&logoColor=white)](https://discord.gg/sjrw8QXNks) | [![Ko-fi](https://shields.io/badge/ko--fi-donate-ff5f5f?logo=ko-fi)](https://ko-fi.com/V7V8JG2FY) [![GitHub Sponsors](https://img.shields.io/badge/sponsor-30363D?logo=GitHub-Sponsors&logoColor=%23EA4AAA)](https://github.com/sponsors/humanbydefinition) |
8
- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
7
+ | [![TypeScript](https://img.shields.io/badge/TypeScript-3178C6?logo=typescript&logoColor=white)](https://www.typescriptlang.org/) [![JSON Schema Draft 2020-12](https://img.shields.io/badge/JSON_Schema-Draft_2020--12-85EA2D?logo=json&logoColor=white)](https://json-schema.org/draft/2020-12) | [![docs](https://img.shields.io/badge/docs-vitepress-646cff?logo=vitepress&logoColor=white)](https://code.textmode.art/) [![Discord](https://img.shields.io/discord/1357070706181017691?color=5865F2&label=Discord&logo=discord&logoColor=white)](https://discord.gg/sjrw8QXNks) | [![Ko-fi](https://shields.io/badge/ko--fi-donate-ff5f5f?logo=ko-fi)](https://ko-fi.com/V7V8JG2FY) [![GitHub Sponsors](https://img.shields.io/badge/sponsor-30363D?logo=GitHub-Sponsors&logoColor=%23EA4AAA)](https://github.com/sponsors/humanbydefinition) |
8
+ | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
9
9
 
10
10
  </div>
11
11
 
12
12
  `@textmode/document` defines a portable, versioned JSON format for textmode artwork. It provides a language-neutral specification, JSON Schema, TypeScript types, and a dependency-free decoder for browsers and Node.js.
13
13
 
14
- The package reads `textmode.document@2.0.0` and migrates `textmode.layer@1.0.0` and `textmode.layer@1.1.0`. The package version and document format version are independent. Updating this library does not change existing files.
14
+ The package defines a unified `textmode.document@3.0.0` structure and reads v2 plus `textmode.layer@1.0.0` and `textmode.layer@1.1.0`. The package version and document format version are independent. Updating this library does not change existing files.
15
15
 
16
16
  ## Install
17
17
 
18
- Install the package from npm:
18
+ Install the published package from npm:
19
19
 
20
20
  ```sh
21
21
  npm install @textmode/document
@@ -35,7 +35,7 @@ const result = parseTextmodeDocumentJSON(jsonText, {
35
35
  if (!result.ok) {
36
36
  console.error(result.error.code, result.error.path, result.error.message);
37
37
  } else {
38
- console.log(result.document.target, result.warnings);
38
+ console.log(result.document.layers.length, result.warnings);
39
39
  }
40
40
  ```
41
41
 
@@ -44,9 +44,10 @@ Successful decoding returns a new canonical document. Colors use RGBA objects, c
44
44
  ## Documentation
45
45
 
46
46
  - [Consumer guide](docs/consumer-guide.md): parsing, schema imports, error handling, resource budgets, and complete examples.
47
- - [Format 2.0 specification](docs/specification-2.0.md): the language-neutral contract for producers and consumers.
48
- - [Maintenance guide](docs/maintenance.md): ownership, compatibility, tests, and release policy.
49
- - [JSON Schema](schemas/2.0/schema.json): also available from `@textmode/document/schema/2.0`.
47
+ - [Format 3.0 specification](docs/specification-3.0.md): the language-neutral contract for producers and consumers.
48
+ - [JSON Schema visual guide](docs/schema-3.0.md): diagrams of document shapes, layers, cells, and validation responsibilities.
49
+ - [Format 2.0 reference](docs/specification-2.0.md) and [visual guide](docs/schema-2.0.md): the older wire format.
50
+ - [JSON Schema](schemas/3.0/schema.json): also available from `@textmode/document/schema/3.0`.
50
51
 
51
52
  The schema identifier is an identifier. It does not promise that the schema is hosted at that URL. Test fixtures are private test data. They are not package exports and are excluded from npm packages.
52
53
 
@@ -7,7 +7,7 @@ export declare const TEXTMODE_DOCUMENT_FORMAT: "textmode.document";
7
7
  * Current textmode document schema revision.
8
8
  *
9
9
  */
10
- export declare const TEXTMODE_DOCUMENT_FORMAT_VERSION: "2.0.0";
10
+ export declare const TEXTMODE_DOCUMENT_FORMAT_VERSION: "3.0.0";
11
11
  /** Legacy format discriminator accepted by the compatibility decoder. */
12
12
  export declare const LEGACY_TEXTMODE_LAYER_FORMAT: "textmode.layer";
13
13
  /** Legacy selected-layer schema revision. */
package/dist/constants.js CHANGED
@@ -7,7 +7,7 @@ export const TEXTMODE_DOCUMENT_FORMAT = 'textmode.document';
7
7
  * Current textmode document schema revision.
8
8
  *
9
9
  */
10
- export const TEXTMODE_DOCUMENT_FORMAT_VERSION = '2.0.0';
10
+ export const TEXTMODE_DOCUMENT_FORMAT_VERSION = '3.0.0';
11
11
  /** Legacy format discriminator accepted by the compatibility decoder. */
12
12
  export const LEGACY_TEXTMODE_LAYER_FORMAT = 'textmode.layer';
13
13
  /** Legacy selected-layer schema revision. */
@@ -1,4 +1,6 @@
1
1
  import type { DecodeContext, UnknownRecord } from './validation.js';
2
- import type { CanonicalTextmodeAllDocument, CanonicalTextmodeSelectedDocument } from './types/index.js';
3
- export declare function decodeSelectedDocument(root: UnknownRecord, context: DecodeContext): CanonicalTextmodeSelectedDocument;
4
- export declare function decodeAllDocument(root: UnknownRecord, context: DecodeContext): CanonicalTextmodeAllDocument;
2
+ import type { CanonicalTextmodeDocument } from './types/index.js';
3
+ export declare function decodeSelectedDocument(root: UnknownRecord, context: DecodeContext): CanonicalTextmodeDocument;
4
+ export declare function decodeAllDocument(root: UnknownRecord, context: DecodeContext): CanonicalTextmodeDocument;
5
+ /** Decode the current unified shape; obsolete structural fields are reserved. */
6
+ export declare function decodeV3Document(root: UnknownRecord, context: DecodeContext): CanonicalTextmodeDocument;
@@ -8,16 +8,22 @@ export function decodeSelectedDocument(root, context) {
8
8
  return {
9
9
  format: TEXTMODE_DOCUMENT_FORMAT,
10
10
  formatVersion: TEXTMODE_DOCUMENT_FORMAT_VERSION,
11
- target: 'selected',
12
11
  ...(root.metadata === undefined
13
12
  ? {}
14
13
  : { metadata: decodeMetadata(root.metadata, '$.metadata', context.limits) }),
15
- canvas,
16
- grid,
17
- layer: {
18
- id: decodeLayerId(layer.id, '$.layer.id', context.limits),
19
- cells: decodeCells(layer.cells, grid, '$.layer.cells', context),
20
- },
14
+ layers: [
15
+ {
16
+ visible: true,
17
+ opacity: 1,
18
+ blendMode: 'normal',
19
+ offsetX: 0,
20
+ offsetY: 0,
21
+ rotationZ: 0,
22
+ grid,
23
+ id: decodeLayerId(layer.id, '$.layer.id', context.limits),
24
+ cells: decodeCells(layer.cells, grid, '$.layer.cells', context),
25
+ },
26
+ ],
21
27
  };
22
28
  }
23
29
  export function decodeAllDocument(root, context) {
@@ -29,22 +35,24 @@ export function decodeAllDocument(root, context) {
29
35
  if (layersValue.length > context.limits.maxLayers) {
30
36
  fail('LIMIT_EXCEEDED', `Layer count ${layersValue.length} exceeds the configured limit ${context.limits.maxLayers}.`, '$.layers');
31
37
  }
32
- const layers = layersValue.map((value, index) => decodeLayer(value, `$.layers[${index}]`, context));
33
- assertCanvasMatchesGrid(canvas, layers[0].grid, '$.canvas');
38
+ const decodedLayers = layersValue.map((value, index) => decodeLayer(value, `$.layers[${index}]`, context, false));
39
+ assertCanvasMatchesGrid(canvas, decodedLayers[0].grid, '$.canvas');
34
40
  return {
35
41
  format: TEXTMODE_DOCUMENT_FORMAT,
36
42
  formatVersion: TEXTMODE_DOCUMENT_FORMAT_VERSION,
37
- target: 'all',
38
43
  ...(root.metadata === undefined
39
44
  ? {}
40
45
  : { metadata: decodeMetadata(root.metadata, '$.metadata', context.limits) }),
41
- canvas,
42
- layers,
46
+ layers: decodedLayers,
43
47
  };
44
48
  }
45
- function decodeLayer(value, path, context) {
49
+ function decodeLayer(value, path, context, validatePixelExtent) {
46
50
  const layer = requireRecord(value, path);
47
51
  const grid = decodeGrid(layer.grid, `${path}.grid`);
52
+ if (validatePixelExtent) {
53
+ checkedProduct(grid.cols, grid.cellWidth, `${path}.grid.cellWidth`);
54
+ checkedProduct(grid.rows, grid.cellHeight, `${path}.grid.cellHeight`);
55
+ }
48
56
  return {
49
57
  id: decodeLayerId(layer.id, `${path}.id`, context.limits),
50
58
  visible: requireBoolean(layer.visible, `${path}.visible`),
@@ -106,3 +114,23 @@ function decodeCell(value, expectedX, expectedY, path, context) {
106
114
  },
107
115
  };
108
116
  }
117
+ /** Decode the current unified shape; obsolete structural fields are reserved. */
118
+ export function decodeV3Document(root, context) {
119
+ for (const key of ['target', 'layer', 'grid', 'canvas']) {
120
+ if (Object.prototype.hasOwnProperty.call(root, key))
121
+ fail('INVALID_DOCUMENT', `Obsolete v3 root field: ${key}.`, `$.${key}`);
122
+ }
123
+ const values = requireArray(root.layers, '$.layers');
124
+ if (values.length === 0)
125
+ fail('INVALID_DOCUMENT', 'A document must contain at least one layer.', '$.layers');
126
+ if (values.length > context.limits.maxLayers)
127
+ fail('LIMIT_EXCEEDED', `Layer count ${values.length} exceeds the configured limit ${context.limits.maxLayers}.`, '$.layers');
128
+ return {
129
+ format: TEXTMODE_DOCUMENT_FORMAT,
130
+ formatVersion: TEXTMODE_DOCUMENT_FORMAT_VERSION,
131
+ ...(root.metadata === undefined
132
+ ? {}
133
+ : { metadata: decodeMetadata(root.metadata, '$.metadata', context.limits) }),
134
+ layers: values.map((value, index) => decodeLayer(value, `$.layers[${index}]`, context, true)),
135
+ };
136
+ }
package/dist/decode.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import { LEGACY_TEXTMODE_ALL_VERSION, LEGACY_TEXTMODE_LAYER_FORMAT, LEGACY_TEXTMODE_SELECTED_VERSION, TEXTMODE_DOCUMENT_FORMAT, TEXTMODE_DOCUMENT_FORMAT_VERSION, } from './constants.js';
2
- import { decodeAllDocument, decodeSelectedDocument } from './decode-shapes.js';
2
+ import { decodeAllDocument, decodeSelectedDocument, decodeV3Document } from './decode-shapes.js';
3
3
  import { parseJSON } from './parse.js';
4
4
  import { DocumentDecodeFailure, fail, failure, requireRecord, requireString, resolveLimits } from './validation.js';
5
5
  /**
@@ -26,7 +26,9 @@ export function decodeTextmodeDocument(value, options = {}) {
26
26
  return {
27
27
  ok: true,
28
28
  document: decodeCurrentDocument(root, context),
29
- warnings: [],
29
+ warnings: root.formatVersion === '2.0.0'
30
+ ? [{ code: 'DOCUMENT_VERSION_MIGRATED', message: 'Migrated textmode.document 2.0.0 to 3.0.0.' }]
31
+ : [],
30
32
  };
31
33
  }
32
34
  if (format === LEGACY_TEXTMODE_LAYER_FORMAT && (options.acceptLegacy ?? true)) {
@@ -36,7 +38,7 @@ export function decodeTextmodeDocument(value, options = {}) {
36
38
  warnings: [
37
39
  {
38
40
  code: 'LEGACY_DOCUMENT_MIGRATED',
39
- message: 'Migrated a legacy textmode.layer document to textmode.document 2.0.0.',
41
+ message: 'Migrated a legacy textmode.layer document to textmode.document 3.0.0.',
40
42
  },
41
43
  ],
42
44
  };
@@ -68,7 +70,9 @@ export function parseTextmodeDocumentJSON(json, options = {}) {
68
70
  }
69
71
  function decodeCurrentDocument(root, context) {
70
72
  const version = requireString(root.formatVersion, '$.formatVersion');
71
- if (version !== TEXTMODE_DOCUMENT_FORMAT_VERSION) {
73
+ if (version === TEXTMODE_DOCUMENT_FORMAT_VERSION)
74
+ return decodeV3Document(root, context);
75
+ if (version !== '2.0.0') {
72
76
  fail('UNSUPPORTED_VERSION', `Unsupported textmode.document version: ${version}.`, '$.formatVersion');
73
77
  }
74
78
  const target = requireString(root.target, '$.target');
package/dist/index.d.ts CHANGED
@@ -2,7 +2,7 @@
2
2
  * Dependency-free textmode document protocol codec.
3
3
  *
4
4
  * This entry point contains no DOM, renderer, textmode.js, or media encoder
5
- * dependencies. It decodes every valid v2 document variant; product-specific
5
+ * dependencies. It decodes v3 and migrates supported v1/v2 documents; product-specific
6
6
  * import policy belongs to callers.
7
7
  *
8
8
  * @packageDocumentation
@@ -10,4 +10,4 @@
10
10
  export { DEFAULT_TEXTMODE_DOCUMENT_LIMITS, LEGACY_TEXTMODE_ALL_VERSION, LEGACY_TEXTMODE_LAYER_FORMAT, LEGACY_TEXTMODE_SELECTED_VERSION, TEXTMODE_DOCUMENT_FORMAT, TEXTMODE_DOCUMENT_FORMAT_VERSION, TEXTMODE_OBJECT_ROWS_ENCODING, } from './constants.js';
11
11
  export { decodeTextmodeDocument, parseTextmodeDocumentJSON } from './decode.js';
12
12
  export { parseJSON } from './parse.js';
13
- export type { CanonicalTextmodeAllDocument, CanonicalTextmodeCell, CanonicalTextmodeCellCollection, CanonicalTextmodeDocument, CanonicalTextmodeDocumentLayer, CanonicalTextmodeSelectedDocument, JSONParseResult, LegacyTextmodeAllDocumentJSON, LegacyTextmodeSelectedDocumentJSON, TextmodeAllDocumentJSON, TextmodeDocumentDecodeOptions, TextmodeDocumentDecodeResult, TextmodeDocumentCell, TextmodeDocumentCellCollection, TextmodeDocumentCellTransform, TextmodeDocumentColor, TextmodeDocumentError, TextmodeDocumentErrorCode, TextmodeDocumentFormat, TextmodeDocumentGrid, TextmodeDocumentJSON, TextmodeDocumentLayer, TextmodeDocumentLimits, TextmodeDocumentMetadata, TextmodeDocumentParseResult, TextmodeDocumentRGBAColor, TextmodeDocumentTarget, TextmodeDocumentVersion, TextmodeDocumentWarning, TextmodeSelectedDocumentJSON, TextmodeSelectedDocumentLayer, } from './types/index.js';
13
+ export type { CanonicalTextmodeCell, CanonicalTextmodeCellCollection, CanonicalTextmodeDocument, CanonicalTextmodeDocumentLayer, JSONParseResult, TextmodeV2SelectedDocumentLayer, TextmodeV2SelectedDocumentJSON, TextmodeV2AllDocumentJSON, TextmodeV2DocumentLayer, LegacyTextmodeAllDocumentJSON, LegacyTextmodeSelectedDocumentJSON, TextmodeDocumentDecodeOptions, TextmodeDocumentDecodeResult, TextmodeDocumentCell, TextmodeDocumentCellCollection, TextmodeDocumentCellTransform, TextmodeDocumentColor, TextmodeDocumentError, TextmodeDocumentErrorCode, TextmodeDocumentFormat, TextmodeDocumentGrid, TextmodeDocumentJSON, TextmodeDocumentLayer, TextmodeDocumentLimits, TextmodeDocumentMetadata, TextmodeDocumentParseResult, TextmodeDocumentRGBAColor, TextmodeDocumentVersion, TextmodeDocumentWarning, } from './types/index.js';
package/dist/index.js CHANGED
@@ -2,7 +2,7 @@
2
2
  * Dependency-free textmode document protocol codec.
3
3
  *
4
4
  * This entry point contains no DOM, renderer, textmode.js, or media encoder
5
- * dependencies. It decodes every valid v2 document variant; product-specific
5
+ * dependencies. It decodes v3 and migrates supported v1/v2 documents; product-specific
6
6
  * import policy belongs to callers.
7
7
  *
8
8
  * @packageDocumentation
@@ -1,24 +1,16 @@
1
- import type { TextmodeDocumentCell, TextmodeDocumentRGBAColor, TextmodeDocumentCellTransform, TextmodeSelectedDocumentJSON, TextmodeDocumentLayer, TextmodeAllDocumentJSON } from './wire.js';
1
+ import type { TextmodeDocumentCell, TextmodeDocumentRGBAColor, TextmodeDocumentLayer, TextmodeDocumentJSON } from './wire.js';
2
2
  import type { TEXTMODE_OBJECT_ROWS_ENCODING } from '../constants.js';
3
- export interface CanonicalTextmodeCell extends Omit<TextmodeDocumentCell, 'foreground' | 'background' | 'transform'> {
3
+ export interface CanonicalTextmodeCell extends Omit<TextmodeDocumentCell, 'foreground' | 'background'> {
4
4
  foreground: TextmodeDocumentRGBAColor;
5
5
  background: TextmodeDocumentRGBAColor;
6
- transform: TextmodeDocumentCellTransform;
7
6
  }
8
7
  export interface CanonicalTextmodeCellCollection {
9
8
  encoding: typeof TEXTMODE_OBJECT_ROWS_ENCODING;
10
9
  rows: CanonicalTextmodeCell[][];
11
10
  }
12
- export interface CanonicalTextmodeSelectedDocument extends Omit<TextmodeSelectedDocumentJSON, 'layer'> {
13
- layer: {
14
- id: string;
15
- cells: CanonicalTextmodeCellCollection;
16
- };
17
- }
18
11
  export interface CanonicalTextmodeDocumentLayer extends Omit<TextmodeDocumentLayer, 'cells'> {
19
12
  cells: CanonicalTextmodeCellCollection;
20
13
  }
21
- export interface CanonicalTextmodeAllDocument extends Omit<TextmodeAllDocumentJSON, 'layers'> {
14
+ export interface CanonicalTextmodeDocument extends Omit<TextmodeDocumentJSON, 'layers'> {
22
15
  layers: CanonicalTextmodeDocumentLayer[];
23
16
  }
24
- export type CanonicalTextmodeDocument = CanonicalTextmodeSelectedDocument | CanonicalTextmodeAllDocument;
@@ -8,6 +8,7 @@ export interface TextmodeDocumentLimits {
8
8
  }
9
9
  export interface TextmodeDocumentDecodeOptions {
10
10
  limits?: TextmodeDocumentLimits;
11
+ /** Accept textmode.layer v1; supported textmode.document v2 is always readable. */
11
12
  acceptLegacy?: boolean;
12
13
  }
13
14
  export type TextmodeDocumentErrorCode = 'INVALID_JSON' | 'INVALID_DOCUMENT' | 'UNSUPPORTED_FORMAT' | 'UNSUPPORTED_VERSION' | 'UNSUPPORTED_TARGET' | 'UNSUPPORTED_ENCODING' | 'LIMIT_EXCEEDED';
@@ -17,7 +18,7 @@ export interface TextmodeDocumentError {
17
18
  path?: string;
18
19
  }
19
20
  export interface TextmodeDocumentWarning {
20
- code: 'LEGACY_DOCUMENT_MIGRATED';
21
+ code: 'LEGACY_DOCUMENT_MIGRATED' | 'DOCUMENT_VERSION_MIGRATED';
21
22
  message: string;
22
23
  }
23
24
  export type JSONParseResult = {
@@ -2,3 +2,4 @@ export type * from './wire.js';
2
2
  export type * from './canonical.js';
3
3
  export type * from './decode.js';
4
4
  export type * from './legacy.js';
5
+ export type * from './v2.js';
@@ -1,5 +1,6 @@
1
1
  import type { LEGACY_TEXTMODE_ALL_VERSION, LEGACY_TEXTMODE_LAYER_FORMAT, LEGACY_TEXTMODE_SELECTED_VERSION } from '../constants.js';
2
- import type { TextmodeDocumentMetadata, TextmodeDocumentGrid, TextmodeSelectedDocumentLayer, TextmodeDocumentLayer } from './wire.js';
2
+ import type { TextmodeDocumentMetadata, TextmodeDocumentGrid } from './wire.js';
3
+ import type { TextmodeV2DocumentLayer, TextmodeV2SelectedDocumentLayer } from './v2.js';
3
4
  export interface LegacyTextmodeSelectedDocumentJSON {
4
5
  $schema?: string;
5
6
  format: typeof LEGACY_TEXTMODE_LAYER_FORMAT;
@@ -10,7 +11,7 @@ export interface LegacyTextmodeSelectedDocumentJSON {
10
11
  height: number;
11
12
  };
12
13
  grid: TextmodeDocumentGrid;
13
- layer: TextmodeSelectedDocumentLayer;
14
+ layer: TextmodeV2SelectedDocumentLayer;
14
15
  }
15
16
  export interface LegacyTextmodeAllDocumentJSON {
16
17
  $schema?: string;
@@ -21,5 +22,5 @@ export interface LegacyTextmodeAllDocumentJSON {
21
22
  width: number;
22
23
  height: number;
23
24
  };
24
- layers: TextmodeDocumentLayer[];
25
+ layers: TextmodeV2DocumentLayer[];
25
26
  }
@@ -0,0 +1,34 @@
1
+ import type { TextmodeDocumentFormat, TextmodeDocumentMetadata, TextmodeDocumentGrid, TextmodeDocumentCellCollection, TextmodeDocumentLayer } from './wire.js';
2
+ export interface TextmodeV2SelectedDocumentLayer {
3
+ id: string;
4
+ cells: TextmodeDocumentCellCollection;
5
+ }
6
+ /** Layer fields required by the v2 wire format and validated during migration. */
7
+ export interface TextmodeV2DocumentLayer extends TextmodeDocumentLayer {
8
+ offsetX: number;
9
+ offsetY: number;
10
+ rotationZ: number;
11
+ }
12
+ export interface TextmodeV2SelectedDocumentJSON {
13
+ format: TextmodeDocumentFormat;
14
+ formatVersion: '2.0.0';
15
+ target: 'selected';
16
+ metadata?: TextmodeDocumentMetadata;
17
+ canvas: {
18
+ width: number;
19
+ height: number;
20
+ };
21
+ grid: TextmodeDocumentGrid;
22
+ layer: TextmodeV2SelectedDocumentLayer;
23
+ }
24
+ export interface TextmodeV2AllDocumentJSON {
25
+ format: TextmodeDocumentFormat;
26
+ formatVersion: '2.0.0';
27
+ target: 'all';
28
+ metadata?: TextmodeDocumentMetadata;
29
+ canvas: {
30
+ width: number;
31
+ height: number;
32
+ };
33
+ layers: TextmodeV2DocumentLayer[];
34
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -1,10 +1,4 @@
1
1
  import type { TEXTMODE_DOCUMENT_FORMAT, TEXTMODE_DOCUMENT_FORMAT_VERSION, TEXTMODE_OBJECT_ROWS_ENCODING } from '../constants.js';
2
- /**
3
- * Scope encoded by a textmode document.
4
- *
5
- * @category JSON document data
6
- */
7
- export type TextmodeDocumentTarget = 'selected' | 'all';
8
2
  /** Format discriminator encoded in a document. */
9
3
  export type TextmodeDocumentFormat = typeof TEXTMODE_DOCUMENT_FORMAT;
10
4
  /** Current on-disk format version, independent of the npm package version. */
@@ -54,22 +48,6 @@ export interface TextmodeDocumentMetadata {
54
48
  version: string;
55
49
  };
56
50
  }
57
- export interface TextmodeSelectedDocumentLayer {
58
- id: string;
59
- cells: TextmodeDocumentCellCollection;
60
- }
61
- export interface TextmodeSelectedDocumentJSON {
62
- format: TextmodeDocumentFormat;
63
- formatVersion: TextmodeDocumentVersion;
64
- target: 'selected';
65
- metadata?: TextmodeDocumentMetadata;
66
- canvas: {
67
- width: number;
68
- height: number;
69
- };
70
- grid: TextmodeDocumentGrid;
71
- layer: TextmodeSelectedDocumentLayer;
72
- }
73
51
  export interface TextmodeDocumentLayer {
74
52
  id: string;
75
53
  visible: boolean;
@@ -81,20 +59,10 @@ export interface TextmodeDocumentLayer {
81
59
  grid: TextmodeDocumentGrid;
82
60
  cells: TextmodeDocumentCellCollection;
83
61
  }
84
- export interface TextmodeAllDocumentJSON {
62
+ /** One portable document with one or more ordered layers, bottom first. */
63
+ export interface TextmodeDocumentJSON {
85
64
  format: TextmodeDocumentFormat;
86
65
  formatVersion: TextmodeDocumentVersion;
87
- target: 'all';
88
66
  metadata?: TextmodeDocumentMetadata;
89
- canvas: {
90
- width: number;
91
- height: number;
92
- };
93
67
  layers: TextmodeDocumentLayer[];
94
68
  }
95
- /**
96
- * JSON document produced by the selected-layer or layer-stack exporter.
97
- *
98
- * @category JSON document data
99
- */
100
- export type TextmodeDocumentJSON = TextmodeSelectedDocumentJSON | TextmodeAllDocumentJSON;