@book.dev/sdk 1.66.0 → 1.68.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.
@@ -0,0 +1,332 @@
1
+ /**
2
+ * **Import asset rehydration (Assets A4).** Turns the image *placeholders* the
3
+ * importers emit (see `import.ts` {@link imagePlaceholderBlock}) into real,
4
+ * rendering `image` blocks — the payoff of OB-ASSETS: an imported picture comes
5
+ * through for real, not as a callout.
6
+ *
7
+ * Two seams, because the bytes arrive two very different ways:
8
+ *
9
+ * - **URL / `data:` images (Markdown · HTML).** These already carry a loadable
10
+ * source, so no upload is needed — {@link rehydrateImageUrls} rewrites the
11
+ * placeholder to an `image` block whose `src` is the original URL (kept as a
12
+ * link) or the inline `data:` URL (which the editor's A2 on-load migration
13
+ * then stores). Pure, DOM-free, no client — runnable *before* the doc is
14
+ * landed, so the page lands already-correct.
15
+ *
16
+ * - **Embedded bytes (Notion zip · opt-in URL download).** A Notion export holds
17
+ * every image's bytes inside the zip; there is no URL to render. So — *after*
18
+ * the page is created (we need its id to ref the asset's read-gate) —
19
+ * {@link rehydrateStoredImages} resolves each placeholder's `ref` to bytes,
20
+ * `putAsset`s them, and rewrites the placeholder to an `image` block holding
21
+ * the returned `assetId`. Content-addressed dedup makes a re-import idempotent.
22
+ *
23
+ * **Never lose the reference.** If the bytes are missing, over the 10 MiB cap, or
24
+ * the upload fails, the block degrades rather than dropping: a loadable URL is
25
+ * preserved as a URL `image` block; anything else keeps its original placeholder
26
+ * (ref + alt intact). A big import's uploads are processed with bounded
27
+ * concurrency so the UI is never blocked, and only pages that actually contain a
28
+ * placeholder are re-read/re-saved (the writers report them in
29
+ * `ImportWriteResult.placeholderPageIds`).
30
+ */
31
+ import { unzipSync } from 'fflate';
32
+ import { IMAGE_PLACEHOLDER_PROP } from './import';
33
+ /** The `image` block type — the native picture block the editor ships (A0/A2). */
34
+ export const IMAGE_BLOCK_TYPE = 'image';
35
+ /**
36
+ * Hard cap on an uploaded asset (10 MiB) — matches the server's asset bodyLimit
37
+ * (`app.ts` `ASSET_MAX_BYTES`). An import image over this stays a placeholder
38
+ * rather than failing the whole import.
39
+ */
40
+ export const DEFAULT_MAX_ASSET_BYTES = 10 * 1024 * 1024;
41
+ // ── ref classification ───────────────────────────────────────────────────────
42
+ const HTTP_RE = /^https?:\/\//i;
43
+ /** Is this an `http(s)` URL — a picture the `image` block can render from `src`? */
44
+ export const isHttpUrl = (s) => HTTP_RE.test(s);
45
+ /** Is this a `data:` URL — inline bytes the editor can render (and A2 migrates)? */
46
+ export const isDataUrlRef = (s) => /^data:/i.test(s);
47
+ /** A loadable source (URL or inline data) the `image` block renders directly. */
48
+ const isLoadableSrc = (s) => isHttpUrl(s) || isDataUrlRef(s);
49
+ /** Rough decoded byte size of a `data:` URL (base64 → 3/4; else the char count). */
50
+ function dataUrlRawBytes(dataUrl) {
51
+ const comma = dataUrl.indexOf(',');
52
+ if (comma < 0)
53
+ return 0;
54
+ const payload = dataUrl.slice(comma + 1);
55
+ return /;base64/i.test(dataUrl.slice(0, comma)) ? Math.floor((payload.length * 3) / 4) : payload.length;
56
+ }
57
+ // ── mime from a ref ──────────────────────────────────────────────────────────
58
+ const MIME_BY_EXT = {
59
+ png: 'image/png',
60
+ jpg: 'image/jpeg',
61
+ jpeg: 'image/jpeg',
62
+ gif: 'image/gif',
63
+ webp: 'image/webp',
64
+ svg: 'image/svg+xml',
65
+ avif: 'image/avif',
66
+ bmp: 'image/bmp',
67
+ ico: 'image/x-icon',
68
+ tif: 'image/tiff',
69
+ tiff: 'image/tiff',
70
+ heic: 'image/heic',
71
+ heif: 'image/heif',
72
+ };
73
+ /** Guess an image mime from a ref's file extension (defaults to octet-stream). */
74
+ export function mimeFromRef(ref) {
75
+ const clean = ref.split('#')[0].split('?')[0];
76
+ const dot = clean.lastIndexOf('.');
77
+ const ext = dot >= 0 ? clean.slice(dot + 1).toLowerCase() : '';
78
+ return MIME_BY_EXT[ext] ?? 'application/octet-stream';
79
+ }
80
+ /** Read the {@link PlaceholderMeta} off a block, or `undefined` if it isn't a placeholder. */
81
+ export function imagePlaceholderMeta(block) {
82
+ return block.props?.[IMAGE_PLACEHOLDER_PROP];
83
+ }
84
+ /**
85
+ * Rewrite an image *placeholder* into a real `image` block, carrying either the
86
+ * uploaded `assetId` or a renderable `src`. The placeholder's `alt` becomes the
87
+ * image alt, its `title` the caption; the deterministic block id is kept so the
88
+ * rewrite is stable across re-imports.
89
+ */
90
+ export function importedImageBlock(placeholder, target) {
91
+ const meta = imagePlaceholderMeta(placeholder) ?? {};
92
+ const props = { ...target };
93
+ if (meta.alt)
94
+ props.alt = meta.alt;
95
+ if (meta.title)
96
+ props.caption = meta.title;
97
+ const block = { type: IMAGE_BLOCK_TYPE, props };
98
+ if (placeholder.id)
99
+ block.id = placeholder.id;
100
+ return block;
101
+ }
102
+ /** Convert an image placeholder to an `image` block when its ref is directly
103
+ * loadable; otherwise leave it (recursing container children). */
104
+ function preserveBlock(block, preserveHttp, maxData) {
105
+ const meta = imagePlaceholderMeta(block);
106
+ if (meta?.ref) {
107
+ const ref = meta.ref;
108
+ if (isHttpUrl(ref) && preserveHttp)
109
+ return importedImageBlock(block, { src: ref });
110
+ if (isDataUrlRef(ref) && dataUrlRawBytes(ref) <= maxData)
111
+ return importedImageBlock(block, { src: ref });
112
+ return block; // relative / zip-path / over-cap data: → leave for the upload pass
113
+ }
114
+ if (block.children && block.children.length > 0) {
115
+ return { ...block, children: block.children.map((c) => preserveBlock(c, preserveHttp, maxData)) };
116
+ }
117
+ return block;
118
+ }
119
+ const preserveRow = (row, preserveHttp, maxData) => ({
120
+ ...row,
121
+ ...(row.blocks ? { blocks: row.blocks.map((b) => preserveBlock(b, preserveHttp, maxData)) } : {}),
122
+ ...(row.children ? { children: row.children.map((c) => preserveRow(c, preserveHttp, maxData)) } : {}),
123
+ });
124
+ const preservePage = (page, preserveHttp, maxData) => ({
125
+ ...page,
126
+ blocks: page.blocks.map((b) => preserveBlock(b, preserveHttp, maxData)),
127
+ ...(page.children ? { children: page.children.map((c) => preservePage(c, preserveHttp, maxData)) } : {}),
128
+ ...(page.database
129
+ ? { database: { ...page.database, rows: page.database.rows.map((r) => preserveRow(r, preserveHttp, maxData)) } }
130
+ : {}),
131
+ });
132
+ /**
133
+ * **Pass 1 (pure).** Rewrite every image placeholder whose ref is a directly
134
+ * loadable source — an `http(s)` URL (preserved as a link) or an in-cap `data:`
135
+ * URL — into a real `image` block, throughout the doc (pages, children, database
136
+ * rows). No client, no I/O: run this on the IR *before* landing it so the page
137
+ * arrives already carrying real images. Idempotent (an `image` block isn't a
138
+ * placeholder, so a re-run is a no-op).
139
+ */
140
+ export function rehydrateImageUrls(doc, opts = {}) {
141
+ const preserveHttp = opts.preserveHttpUrls !== false;
142
+ const maxData = opts.maxDataBytes ?? DEFAULT_MAX_ASSET_BYTES;
143
+ return { pages: doc.pages.map((p) => preservePage(p, preserveHttp, maxData)) };
144
+ }
145
+ /** Build a limiter that keeps at most `max` calls in flight at once (FIFO queue). */
146
+ function createLimiter(max) {
147
+ let active = 0;
148
+ const queue = [];
149
+ const pump = () => {
150
+ if (active >= max)
151
+ return;
152
+ const run = queue.shift();
153
+ if (!run)
154
+ return;
155
+ active += 1;
156
+ run();
157
+ };
158
+ return (fn) => new Promise((resolve, reject) => {
159
+ queue.push(() => {
160
+ fn()
161
+ .then(resolve, reject)
162
+ .finally(() => {
163
+ active -= 1;
164
+ pump();
165
+ });
166
+ });
167
+ pump();
168
+ });
169
+ }
170
+ /** Rehydrate a single page's placeholder blocks in place (recursing children). */
171
+ async function rehydratePage(client, pageId, resolve, maxBytes, stats, limit) {
172
+ let page;
173
+ try {
174
+ page = await client.getPage(pageId);
175
+ }
176
+ catch {
177
+ return; // a page we can't read — skip, never crash the import
178
+ }
179
+ if (!page)
180
+ return;
181
+ const blockdoc = page.data?.blockdoc;
182
+ const blocks = blockdoc?.blocks;
183
+ if (!blocks || blocks.length === 0)
184
+ return;
185
+ let changed = false;
186
+ // Resolve + upload one placeholder. Run through the shared `limit` so total
187
+ // in-flight uploads stay bounded regardless of how many images a page holds
188
+ // (an image-dense page must not fan out N uploads at once and flood the socket).
189
+ const rehydrateOne = async (block, ref) => {
190
+ let resolved = null;
191
+ try {
192
+ resolved = await resolve(ref);
193
+ }
194
+ catch {
195
+ resolved = null;
196
+ }
197
+ if (resolved && resolved.bytes.byteLength > 0 && resolved.bytes.byteLength <= maxBytes) {
198
+ try {
199
+ const { id } = await client.putAsset(resolved.bytes, resolved.mime, pageId);
200
+ changed = true;
201
+ stats.uploaded += 1;
202
+ return importedImageBlock(block, { assetId: id });
203
+ }
204
+ catch {
205
+ // Upload failed (transient / 413) — fall through to the degrade paths.
206
+ }
207
+ }
208
+ // Degrade without dropping: a loadable ref survives as a URL/data image
209
+ // block; anything else keeps its placeholder (ref + alt intact). An over-cap
210
+ // `data:` blob is NOT re-inlined — Pass 1 excluded it to protect the CRDT.
211
+ if (isLoadableSrc(ref) && !(isDataUrlRef(ref) && dataUrlRawBytes(ref) > maxBytes)) {
212
+ changed = true;
213
+ stats.preservedUrls += 1;
214
+ return importedImageBlock(block, { src: ref });
215
+ }
216
+ stats.keptPlaceholders += 1;
217
+ return block;
218
+ };
219
+ const mapBlock = async (block) => {
220
+ const meta = imagePlaceholderMeta(block);
221
+ if (meta?.ref) {
222
+ const ref = meta.ref;
223
+ return limit(() => rehydrateOne(block, ref));
224
+ }
225
+ if (block.children && block.children.length > 0) {
226
+ const kids = await Promise.all(block.children.map(mapBlock));
227
+ return { ...block, children: kids };
228
+ }
229
+ return block;
230
+ };
231
+ const next = await Promise.all(blocks.map(mapBlock));
232
+ if (!changed)
233
+ return;
234
+ const data = { ...page.data, blockdoc: { ...(blockdoc ?? {}), blocks: next } };
235
+ try {
236
+ await client.savePage({ id: page.id, name: page.name, data });
237
+ }
238
+ catch {
239
+ // A failed re-save leaves the placeholders in place — degraded, not lost.
240
+ }
241
+ }
242
+ /**
243
+ * **Pass 2 (post-import).** For each page id carrying an image placeholder (the
244
+ * writers report these in `ImportWriteResult.placeholderPageIds`), resolve every
245
+ * placeholder's bytes and — within the size cap — `putAsset` + rewrite it to an
246
+ * `assetId` `image` block, then re-save the page. A single shared limiter caps
247
+ * total in-flight uploads (across all pages and all images) so a large,
248
+ * image-dense import streams rather than flooding the socket. Degrades safely
249
+ * (never loses a ref); idempotent (a re-run finds real images, not placeholders,
250
+ * and content-addressed dedup returns the same `assetId`).
251
+ */
252
+ export async function rehydrateStoredImages(client, pageIds, resolve, opts = {}) {
253
+ const maxBytes = opts.maxAssetBytes ?? DEFAULT_MAX_ASSET_BYTES;
254
+ const concurrency = Math.max(1, opts.concurrency ?? 4);
255
+ const stats = { uploaded: 0, preservedUrls: 0, keptPlaceholders: 0 };
256
+ const ids = [...new Set(pageIds)];
257
+ if (ids.length === 0)
258
+ return stats;
259
+ // ONE limiter shared across every page: it caps total in-flight uploads, so an
260
+ // image-dense page can't fan out N `putAsset`s at once (which would flood the
261
+ // IPC socket / server), independent of how pages/images are distributed.
262
+ const limit = createLimiter(concurrency);
263
+ let cursor = 0;
264
+ let done = 0;
265
+ const worker = async () => {
266
+ while (cursor < ids.length) {
267
+ const pageId = ids[cursor];
268
+ cursor += 1;
269
+ await rehydratePage(client, pageId, resolve, maxBytes, stats, limit);
270
+ done += 1;
271
+ opts.onProgress?.(done, ids.length);
272
+ }
273
+ };
274
+ await Promise.all(Array.from({ length: Math.min(concurrency, ids.length) }, worker));
275
+ return stats;
276
+ }
277
+ // ── Resolvers ────────────────────────────────────────────────────────────────
278
+ /**
279
+ * Build a resolver over a Notion export zip: a placeholder `ref` (rewritten by
280
+ * {@link notionExportToImportedDoc} to the absolute in-zip path) → its bytes +
281
+ * a mime guessed from the extension. Unzips lazily on first use (the import may
282
+ * land no images), and answers `null` for a ref with no matching entry.
283
+ */
284
+ export function notionAssetResolver(zipBytes) {
285
+ let entries = null;
286
+ const ensure = () => {
287
+ if (!entries) {
288
+ try {
289
+ entries = unzipSync(zipBytes);
290
+ }
291
+ catch {
292
+ entries = {};
293
+ }
294
+ }
295
+ return entries;
296
+ };
297
+ return (ref) => {
298
+ const bytes = ensure()[ref];
299
+ if (!bytes)
300
+ return null;
301
+ return { bytes, mime: mimeFromRef(ref) };
302
+ };
303
+ }
304
+ /**
305
+ * Build a resolver that downloads an `http(s)` image `ref` into bytes — the
306
+ * opt-in "store a copy of each linked image" path. Uses the ambient `fetch` when
307
+ * no impl is passed. Answers `null` (→ the URL is preserved as a link) for a
308
+ * non-http ref, a non-OK response, an empty body, or any fetch error — a slow /
309
+ * failing / cross-origin link degrades rather than breaking the import.
310
+ */
311
+ export function urlAssetResolver(fetchImpl) {
312
+ const doFetch = fetchImpl ?? (typeof fetch !== 'undefined' ? fetch : null);
313
+ return async (ref) => {
314
+ if (!isHttpUrl(ref) || !doFetch)
315
+ return null;
316
+ try {
317
+ const res = await doFetch(ref);
318
+ if (!res.ok)
319
+ return null;
320
+ const bytes = new Uint8Array(await res.arrayBuffer());
321
+ if (bytes.byteLength === 0)
322
+ return null;
323
+ const headerMime = res.headers?.get('content-type')?.split(';')[0]?.trim();
324
+ const mime = headerMime && headerMime.startsWith('image/') ? headerMime : mimeFromRef(ref);
325
+ return { bytes, mime };
326
+ }
327
+ catch {
328
+ return null;
329
+ }
330
+ };
331
+ }
332
+ //# sourceMappingURL=importAssets.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"importAssets.js","sourceRoot":"","sources":["../src/importAssets.ts"],"names":[],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -10,18 +10,22 @@ export { evaluateFormula, formulaReferences, FormulaError, type FormulaValue, ty
10
10
  export { OWNER_PROPERTY_ID, VERIFICATION_PROPERTY_ID, BACKLINKS_PROPERTY_ID, THEME_PROPERTY_ID, COVER_PROPERTY_ID, FONTS_PROPERTY_ID, ICON_PROPERTY_ID, FULLWIDTH_PROPERTY_ID, SYSTEM_PAGE_PROPERTIES, isVerified, verificationExpired, isVerificationActive, makeVerification, extractMentionIds, propertiesReferencePage, type VerificationValue, } from './pageProperties';
11
11
  export { getServerUrlOverride, setServerUrlOverride, getServerTokenOverride, setServerTokenOverride, getIdentityCredential, setIdentityToken, setGuestName, getForwardingAudience, setForwardingAudience, isMixedContentBlocked } from './connection';
12
12
  export { AccountClient, AccountError, DEFAULT_ACCOUNT_URL, getAccountUrlOverride, setAccountUrlOverride, resolveAccountUrl, type AccountSettings, } from './account';
13
- export { guestPrincipal, localPrincipal, principalId, mintIdentityKeypair, signIdentity, decodeIdentity, verifyIdentity, verifyRevocations, signRevocations, principalFromClaims, unverifiedPrincipalFromClaims, type Principal, type PrincipalKind, type VerifiedVia, type IdentityHeader, type IdentityClaims, type Jwk, type Jwks, type RevocationEntry, type RevocationSet, type IdentityKeypair, type VerifyOptions, type VerifyResult, type VerifyFailure, } from './identity';
13
+ export { guestPrincipal, localPrincipal, principalId, verifiedSubject, colorForIdentity, IDENTITY_COLORS, mintIdentityKeypair, signIdentity, decodeIdentity, verifyIdentity, verifyRevocations, signRevocations, principalFromClaims, unverifiedPrincipalFromClaims, type Principal, type PrincipalKind, type VerifiedVia, type IdentityHeader, type IdentityClaims, type Jwk, type Jwks, type RevocationEntry, type RevocationSet, type IdentityKeypair, type VerifyOptions, type VerifyResult, type VerifyFailure, } from './identity';
14
14
  export { DEFAULT_INSTANCE_CONFIG, type GuestAccess, type TrustedIssuerConfig, type InstanceConfig, type InstanceInfo, type StoredEdit, type WorkspaceBinding, type WorkspaceRoster, type WorkspaceRosterEntry, } from './provenance';
15
15
  export { authorize, isEmailAuthoritative, type Role, type EffectiveVisibility, type AclEntry, type AccessPage, type AccessCtx, type Decision, } from './authorize';
16
16
  export { snapshotText, paragraphBlocks, textSnapshot, appendTextToSnapshot, appendBlocksToSnapshot, type AppendBlock } from './content';
17
17
  export { snapshotBlocks, contentHash, computeBlockMtimes, stampSnapshotMtimes, latestBlockMtime, type BlockDigest, } from './mtime';
18
- export { computeBlockAuthors, stampSnapshotAuthors, latestSnapshotAuthor } from './authors';
18
+ export { computeBlockAuthors, stampSnapshotAuthors, stampSnapshotAuthorsPerBlock, latestSnapshotAuthor, type BlockAuthorResolver, } from './authors';
19
19
  export { pageToBookHtml, bookHtmlToPage, readBookHtmlMeta, slugify, type BookPageRecord, } from './bookfile';
20
20
  export { spaceToBookFiles, parseBookFolder, SPACE_BUNDLE_FILE, type BookFolderFile, type SpaceSnapshot, } from './bookFolder';
21
21
  export { canonicalDigest, generateRegistryKeys, signPlugin, verifyPlugin, validateManifest, OPENBOOK_REGISTRY, type PluginManifest, type PluginAgentTool, type PluginPackage, type PluginSignature, type StoredPlugin, } from './plugins';
22
22
  export { buildSampleDocument, seedSampleDocument, SAMPLE_DOCUMENT_NAME } from './sampleDocument';
23
23
  export type { CommentRun, AuthoredIdentity, SuggestionAuthorKind, SuggestionKind, SuggestionStatus, SuggestionTarget, StoredSuggestion, SuggestionInput, SuggestionUpdate, StoredComment, CommentInput, } from './suggestions';
24
24
  export { PAGE_TEMPLATES, instantiateTemplate, type PageTemplate } from './templates';
25
+ export { imagePlaceholderBlock, imagePlaceholderCell, importedBlocksToSnapshot, chooseStrategy, writeViaCreateApis, buildImportBundle, writeViaBundle, importDoc, IMAGE_PLACEHOLDER_KIND, IMAGE_PLACEHOLDER_PROP, type ImportInlineAttrs, type ImportTextRun, type ImportedBlock, type ImportedAsset, type ImportedRow, type ImportedDatabase, type ImportedPage, type ImportedDoc, type ImportStrategy, type ImportWriteClient, type ImportOptions, type BundleOptions, type ImportWriteResult, blocksHaveImagePlaceholder, } from './import';
26
+ export { markdownToBlocks, markdownToImportedDoc, type MarkdownImportOptions } from './markdownImport';
27
+ export { notionExportToImportedDoc, parseCsv } from './notionImport';
28
+ export { rehydrateImageUrls, rehydrateStoredImages, importedImageBlock, imagePlaceholderMeta, mimeFromRef, notionAssetResolver, urlAssetResolver, isHttpUrl, isDataUrlRef, IMAGE_BLOCK_TYPE, DEFAULT_MAX_ASSET_BYTES, type RehydrateUrlOptions, type RehydrateStoredClient, type RehydrateStoredOptions, type RehydrateStoredResult, type ImportAssetResolver, type AssetBytes, } from './importAssets';
25
29
  export { BACKUP_VERSION, BACKUP_CADENCES, BACKUP_CADENCE_MS, DEFAULT_BACKUP_CONFIG, remapBundle, type SpaceBackup, type ImportMode, type ImportRequest, type ImportResult, type BackupCadence, type BackupConfig, type BackupCadenceStatus, type BackupStatus, } from './backup';
26
30
  export type { AgentChatEvent, AgentChatMessage, AgentChatOptions, AgentProposal, InterviewStep, AiProvider, AiConfig, AiProviderSettings, AiEffort, AiSkill, AiStatus, AiSearchResult, AiSearchResponse, AiTasksResponse, AiStreamEvent, } from './ai';
27
31
  export { providerSettings, isPaidProvider } from './ai';
package/dist/index.js CHANGED
@@ -7,17 +7,21 @@ export { evaluateFormula, formulaReferences, FormulaError, } from './formula';
7
7
  export { OWNER_PROPERTY_ID, VERIFICATION_PROPERTY_ID, BACKLINKS_PROPERTY_ID, THEME_PROPERTY_ID, COVER_PROPERTY_ID, FONTS_PROPERTY_ID, ICON_PROPERTY_ID, FULLWIDTH_PROPERTY_ID, SYSTEM_PAGE_PROPERTIES, isVerified, verificationExpired, isVerificationActive, makeVerification, extractMentionIds, propertiesReferencePage, } from './pageProperties';
8
8
  export { getServerUrlOverride, setServerUrlOverride, getServerTokenOverride, setServerTokenOverride, getIdentityCredential, setIdentityToken, setGuestName, getForwardingAudience, setForwardingAudience, isMixedContentBlocked } from './connection';
9
9
  export { AccountClient, AccountError, DEFAULT_ACCOUNT_URL, getAccountUrlOverride, setAccountUrlOverride, resolveAccountUrl, } from './account';
10
- export { guestPrincipal, localPrincipal, principalId, mintIdentityKeypair, signIdentity, decodeIdentity, verifyIdentity, verifyRevocations, signRevocations, principalFromClaims, unverifiedPrincipalFromClaims, } from './identity';
10
+ export { guestPrincipal, localPrincipal, principalId, verifiedSubject, colorForIdentity, IDENTITY_COLORS, mintIdentityKeypair, signIdentity, decodeIdentity, verifyIdentity, verifyRevocations, signRevocations, principalFromClaims, unverifiedPrincipalFromClaims, } from './identity';
11
11
  export { DEFAULT_INSTANCE_CONFIG, } from './provenance';
12
12
  export { authorize, isEmailAuthoritative, } from './authorize';
13
13
  export { snapshotText, paragraphBlocks, textSnapshot, appendTextToSnapshot, appendBlocksToSnapshot } from './content';
14
14
  export { snapshotBlocks, contentHash, computeBlockMtimes, stampSnapshotMtimes, latestBlockMtime, } from './mtime';
15
- export { computeBlockAuthors, stampSnapshotAuthors, latestSnapshotAuthor } from './authors';
15
+ export { computeBlockAuthors, stampSnapshotAuthors, stampSnapshotAuthorsPerBlock, latestSnapshotAuthor, } from './authors';
16
16
  export { pageToBookHtml, bookHtmlToPage, readBookHtmlMeta, slugify, } from './bookfile';
17
17
  export { spaceToBookFiles, parseBookFolder, SPACE_BUNDLE_FILE, } from './bookFolder';
18
18
  export { canonicalDigest, generateRegistryKeys, signPlugin, verifyPlugin, validateManifest, OPENBOOK_REGISTRY, } from './plugins';
19
19
  export { buildSampleDocument, seedSampleDocument, SAMPLE_DOCUMENT_NAME } from './sampleDocument';
20
20
  export { PAGE_TEMPLATES, instantiateTemplate } from './templates';
21
+ export { imagePlaceholderBlock, imagePlaceholderCell, importedBlocksToSnapshot, chooseStrategy, writeViaCreateApis, buildImportBundle, writeViaBundle, importDoc, IMAGE_PLACEHOLDER_KIND, IMAGE_PLACEHOLDER_PROP, blocksHaveImagePlaceholder, } from './import';
22
+ export { markdownToBlocks, markdownToImportedDoc } from './markdownImport';
23
+ export { notionExportToImportedDoc, parseCsv } from './notionImport';
24
+ export { rehydrateImageUrls, rehydrateStoredImages, importedImageBlock, imagePlaceholderMeta, mimeFromRef, notionAssetResolver, urlAssetResolver, isHttpUrl, isDataUrlRef, IMAGE_BLOCK_TYPE, DEFAULT_MAX_ASSET_BYTES, } from './importAssets';
21
25
  export { BACKUP_VERSION, BACKUP_CADENCES, BACKUP_CADENCE_MS, DEFAULT_BACKUP_CONFIG, remapBundle, } from './backup';
22
26
  export { providerSettings, isPaidProvider } from './ai';
23
27
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,79 @@
1
+ /**
2
+ * **Markdown / GFM → blocks importer.** Turns a CommonMark + GFM source string
3
+ * into the format-agnostic {@link ImportedDoc} IR (see `import.ts`), so
4
+ * {@link importDoc} can land it through the existing data paths. A parser's only
5
+ * job is this transform; it never touches the store, the CRDT, or the wire.
6
+ *
7
+ * **Parser choice — `marked`.** It is pure JS with zero runtime dependencies,
8
+ * ships first-class GFM (tables, task lists, strikethrough, autolinks), and —
9
+ * crucially — exposes a structured token AST via {@link lexer} (block tokens
10
+ * carry their inline children in `.tokens`). That lets us map tokens → blocks
11
+ * directly, with NO DOM. The UI's `htmlToRuns`/`htmlToBlocks` are deliberately
12
+ * *not* reused: they are `document`-bound (they return stripped plain text when
13
+ * `document` is undefined) and live in `@book.dev/ui`, which depends on the SDK —
14
+ * importing them here would invert that dependency. We build runs from marked's
15
+ * inline tokens instead.
16
+ *
17
+ * **Block mapping** (shapes cited from `@book.dev/ui`'s `blockeditor/model.ts`):
18
+ *
19
+ * | Markdown / GFM | Block (`ImportedBlock`) |
20
+ * | ------------------------- | ----------------------------------------------- |
21
+ * | `# … ######` heading | `heading` · `props.level` 1–3 (clamped, as editor)|
22
+ * | paragraph | `paragraph` |
23
+ * | `-`/`*`/`+` list | `list` · `props.kind:'bullet'` |
24
+ * | `1.` ordered list | `list` · `props.kind:'number'` |
25
+ * | nested list item | flat `list`/`todo` · `props.indent` = depth |
26
+ * | `- [ ]` / `- [x]` task | `todo` · `props.checked` |
27
+ * | `>` blockquote | `quote` (block children folded to its rich text) |
28
+ * | ```` ``` ```` fenced code | `code` · `props.language` |
29
+ * | GFM table | `table` → `row` → `cell` children |
30
+ * | `---` thematic break | `divider` |
31
+ * | `**`/`*`/`~~`/`` ` ``/link | inline `runs` (`{b,i,s,c,a}`) |
32
+ * | `![alt](src)` image | {@link imagePlaceholderBlock} (block) / linked run (cell)|
33
+ * | raw HTML / unknown | degrades to a `paragraph` — never dropped |
34
+ *
35
+ * **Images.** An image never vanishes: in body content it becomes the import
36
+ * core's {@link imagePlaceholderBlock} (preserving `src` + `alt` + `title`); in
37
+ * a table cell — which can hold only inline text — it becomes a link run to the
38
+ * `src` carrying the `alt`. **Unknown / unsupported constructs** degrade to a
39
+ * paragraph of their text, honoring the converter contract that import content
40
+ * is "never silently dropped" (`model.ts`).
41
+ *
42
+ * **Front-matter.** A leading `---` YAML block is read for `title:` (used as the
43
+ * page title); the remaining lines are passed through verbatim as a `yaml` code
44
+ * block rather than dropped.
45
+ */
46
+ import { type ImportedBlock, type ImportedDoc } from './import';
47
+ /** Options for {@link markdownToImportedDoc}. */
48
+ export interface MarkdownImportOptions {
49
+ /** Explicit page title — overrides front-matter and any leading heading. */
50
+ title?: string;
51
+ /** Title used when none can be derived. Default `'Imported document'`. */
52
+ defaultTitle?: string;
53
+ /**
54
+ * When no explicit/front-matter title is given, promote a leading heading to
55
+ * the page title (consuming it from the body). Default `true`.
56
+ */
57
+ firstHeadingAsTitle?: boolean;
58
+ }
59
+ /**
60
+ * Parse a Markdown/GFM string into {@link ImportedBlock}s. Pure and DOM-free, so
61
+ * it is directly unit-testable and reusable wherever only the block list is
62
+ * wanted (e.g. importing a fragment into an existing page). Honors the
63
+ * "never silently drop content" contract: unknown constructs degrade to text,
64
+ * images become placeholders.
65
+ */
66
+ export declare function markdownToBlocks(markdown: string): ImportedBlock[];
67
+ /**
68
+ * Parse a full Markdown/GFM document into an {@link ImportedDoc} (a single page)
69
+ * ready for {@link importDoc}. The page title is resolved as:
70
+ *
71
+ * 1. `opts.title` (explicit), else
72
+ * 2. front-matter `title:`, else
73
+ * 3. a leading heading promoted to the title (consumed from the body) when
74
+ * `opts.firstHeadingAsTitle !== false`, else
75
+ * 4. `opts.defaultTitle` (default `'Imported document'`).
76
+ *
77
+ * Any non-title front-matter is preserved as a leading `yaml` code block.
78
+ */
79
+ export declare function markdownToImportedDoc(markdown: string, opts?: MarkdownImportOptions): ImportedDoc;