@shayc/open-board-format 1.3.3 → 1.3.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.
Files changed (3) hide show
  1. package/CHANGELOG.md +6 -0
  2. package/README.md +35 -53
  3. package/package.json +1 -1
package/CHANGELOG.md CHANGED
@@ -1,5 +1,11 @@
1
1
  # @shayc/open-board-format
2
2
 
3
+ ## 1.3.4
4
+
5
+ ### Patch Changes
6
+
7
+ - ea8b3f6: Clarify the README introduction and `loadBoard` usage example.
8
+
3
9
  ## 1.3.3
4
10
 
5
11
  ### Patch Changes
package/README.md CHANGED
@@ -3,11 +3,9 @@
3
3
  [![npm version](https://img.shields.io/npm/v/@shayc/open-board-format)](https://www.npmjs.com/package/@shayc/open-board-format)
4
4
  [![CI](https://github.com/shayc/open-board-format/actions/workflows/ci.yml/badge.svg)](https://github.com/shayc/open-board-format/actions/workflows/ci.yml)
5
5
 
6
- Parse, validate, and create [Open Board Format](https://www.openboardformat.org/) (OBF) communication boards (`.obf`) and archives (`.obz`) for augmentative and alternative communication (AAC) applications in TypeScript or JavaScript.
6
+ A TypeScript/JavaScript library for parsing, validating, and creating [Open Board Format](https://www.openboardformat.org/) (OBF) communication boards (`.obf`) and archives (`.obz`) for AAC applications.
7
7
 
8
- Add AAC board import and export without implementing schemas, manifests, or archive handling yourself.
9
-
10
- The package handles format detection, validation, archive creation, and schema access so applications can focus on board experiences instead of file handling.
8
+ Add Open Board Format import and export without implementing schemas, manifests, or archive handling yourself.
11
9
 
12
10
  ## Features
13
11
 
@@ -15,7 +13,6 @@ The package handles format detection, validation, archive creation, and schema a
15
13
  - Create OBZ archives with generated manifests and validated media resources.
16
14
  - Use exported [Zod](https://zod.dev/) schemas and inferred TypeScript types.
17
15
  - Preserve unknown fields, including vendor extensions.
18
- - Run as pure ESM in Node.js 22+ and modern browsers.
19
16
 
20
17
  It focuses on board data and archives only. It does not render boards, play media, fetch remote resources, or resolve navigation and media references.
21
18
 
@@ -27,20 +24,21 @@ npm install @shayc/open-board-format zod
27
24
 
28
25
  `zod ^4.4.3` is a required peer dependency.
29
26
 
27
+ Works in browsers and Node.js. Browser `File` uploads and Node.js `Buffer` values use the same loading API. Pure ESM; CommonJS is not supported.
28
+
30
29
  ## Quick start
31
30
 
32
31
  ```ts
33
32
  import { loadBoard } from "@shayc/open-board-format";
34
- import type { BinaryInput, OBFBoard } from "@shayc/open-board-format";
35
33
 
36
- export async function loadRootBoard(input: BinaryInput): Promise<OBFBoard> {
37
- const loaded = await loadBoard(input);
38
-
39
- return loaded.format === "obf" ? loaded.board : loaded.archive.rootBoard;
40
- }
34
+ const loaded = await loadBoard(input);
41
35
  ```
42
36
 
43
- `BinaryInput` accepts `File`, `Blob`, `ArrayBuffer`, and `ArrayBufferView` values, including browser files, fetched blobs, typed arrays, and Node.js `Buffer` values. `loadBoard` detects the format from the bytes, not the filename.
37
+ `loadBoard` accepts a `File`, `Blob`, `ArrayBuffer`, or `ArrayBufferView` and detects the format from the bytes, not the filename. It returns a TypeScript discriminated union: OBF files contain a board directly, while OBZ files contain an archive whose `rootBoard` is the entry point.
38
+
39
+ ```ts
40
+ const board = loaded.format === "obf" ? loaded.board : loaded.archive.rootBoard;
41
+ ```
44
42
 
45
43
  ## Formats
46
44
 
@@ -92,32 +90,16 @@ For untrusted archives, configure [extraction limits](#extraction-limits).
92
90
 
93
91
  ### Create an OBZ archive
94
92
 
95
- Buttons reference media by ID. Image and sound records declare archive paths, while the `resources` map supplies the bytes stored at those paths.
93
+ Given an existing board and its media resources:
96
94
 
97
95
  ```ts
98
- import { readFile, writeFile } from "node:fs/promises";
99
96
  import { createOBZ } from "@shayc/open-board-format";
100
- import type { OBFBoard } from "@shayc/open-board-format";
101
-
102
- const board: OBFBoard = {
103
- format: "open-board-0.1",
104
- id: "board-1",
105
- buttons: [{ id: "btn-1", label: "Hello", image_id: "img-1" }],
106
- grid: { rows: 1, columns: 1, order: [["btn-1"]] },
107
- images: [{ id: "img-1", path: "images/hello.png" }],
108
- };
109
97
 
110
- const pngBytes = await readFile("hello.png");
111
- const resources = new Map([["images/hello.png", pngBytes]]);
112
-
113
- const blob = await createOBZ([board], "board-1", resources);
114
- await writeFile("my-board.obz", new Uint8Array(await blob.arrayBuffer()));
98
+ const blob = await createOBZ([existingBoard], existingBoard.id, resources);
115
99
  ```
116
100
 
117
101
  `createOBZ` generates the manifest automatically, writes boards to `boards/<encoded-id>.obf`, and uses `rootBoardId` as the archive's entry board.
118
102
 
119
- Before writing the archive, it checks board IDs, the root board, generated paths, media-path conflicts, and declared media resources. It does not resolve `load_board`, `image_id`, or `sound_id` references.
120
-
121
103
  ### Validate a board
122
104
 
123
105
  ```ts
@@ -129,7 +111,7 @@ export const validateBoard = (value: unknown) =>
129
111
 
130
112
  Every public OBF data model has a matching Zod schema export with a `Schema` suffix. The schemas can also be composed with Zod APIs such as `.extend()` and `.pick()`.
131
113
 
132
- ## Validation behavior
114
+ ## Validation details
133
115
 
134
116
  Validation returns a parsed copy of the input. Known fields may be normalized during parsing:
135
117
 
@@ -158,7 +140,7 @@ Add application-specific checks after parsing when those guarantees matter.
158
140
 
159
141
  ## API reference
160
142
 
161
- ### Functions
143
+ ### High-level API
162
144
 
163
145
  #### Board data
164
146
 
@@ -179,13 +161,7 @@ Add application-specific checks after parsing when those guarantees matter.
179
161
  | `createOBZ(boards, rootBoardId, resources?)` | `Promise<Blob>` | Validate and package boards and resources with a generated manifest |
180
162
  | `parseManifest(json)` | `OBFManifest` | Parse and validate manifest JSON |
181
163
 
182
- #### ZIP utilities
183
-
184
- | Function | Returns | Behavior |
185
- | ------------------------- | ---------------------------------- | -------------------------------------------------------- |
186
- | `isZip(buffer)` | `boolean` | Check whether an `ArrayBuffer` has a ZIP signature |
187
- | `zip(entries)` | `Promise<Uint8Array>` | Compress a map of paths to `Uint8Array` or `ArrayBuffer` |
188
- | `unzip(buffer, options?)` | `Promise<Map<string, Uint8Array>>` | Extract an `ArrayBuffer` and omit directory markers |
164
+ Before writing an archive, `createOBZ` checks board IDs, the root board, generated paths, media-path conflicts, and declared media resources. It does not resolve `load_board`, `image_id`, or `sound_id` references.
189
165
 
190
166
  ### Types and schemas
191
167
 
@@ -222,22 +198,15 @@ Branch on `error.info.code`, not `error.message`.
222
198
 
223
199
  ```ts
224
200
  import { loadBoard, OBFError } from "@shayc/open-board-format";
225
- import type { BinaryInput } from "@shayc/open-board-format";
226
-
227
- export async function openBoard(input: BinaryInput) {
228
- try {
229
- return await loadBoard(input);
230
- } catch (error) {
231
- if (!(error instanceof OBFError)) throw error;
232
201
 
233
- if (error.info.code === "invalid-board") {
234
- console.error(error.info.issues);
235
- } else {
236
- console.error(error.message);
237
- }
238
-
239
- throw error;
202
+ try {
203
+ await loadBoard(file);
204
+ } catch (error) {
205
+ if (error instanceof OBFError) {
206
+ console.error(error.info.code);
240
207
  }
208
+
209
+ throw error;
241
210
  }
242
211
  ```
243
212
 
@@ -271,6 +240,19 @@ Validation failures expose the underlying `ZodError` as `error.cause` and provid
271
240
 
272
241
  Direct schema `.parse()` calls throw `ZodError` rather than `OBFError`.
273
242
 
243
+ <details>
244
+ <summary><strong>Low-level ZIP utilities</strong></summary>
245
+
246
+ The following exports are available for advanced archive workflows:
247
+
248
+ | Function | Returns | Behavior |
249
+ | ------------------------- | ---------------------------------- | -------------------------------------------------------- |
250
+ | `isZip(buffer)` | `boolean` | Check whether an `ArrayBuffer` has a ZIP signature |
251
+ | `zip(entries)` | `Promise<Uint8Array>` | Compress a map of paths to `Uint8Array` or `ArrayBuffer` |
252
+ | `unzip(buffer, options?)` | `Promise<Map<string, Uint8Array>>` | Extract an `ArrayBuffer` and omit directory markers |
253
+
254
+ </details>
255
+
274
256
  ## Security
275
257
 
276
258
  Treat OBZ archives and their contents as untrusted input.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@shayc/open-board-format",
3
- "version": "1.3.3",
3
+ "version": "1.3.4",
4
4
  "description": "Parse, validate, and create Open Board Format (.obf/.obz) files — the open standard for Augmentative and Alternative Communication (AAC) boards. TypeScript, browser and Node.js.",
5
5
  "license": "MIT",
6
6
  "author": "Shay Cojocaru <shayc@outlook.com>",