@w100n/documents 0.16.4 → 0.17.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.
Files changed (44) hide show
  1. package/dist/{Compare-M57FG4R3.js → Compare-RHAUAKUJ.js} +2 -2
  2. package/dist/{SheetView-OEKOHMKW.js → SheetView-SBLAFGTL.js} +5 -5
  3. package/dist/{TextEditor-5S7FSLIZ.js → TextEditor-X2GSL4QM.js} +119 -27
  4. package/dist/TextEditor-X2GSL4QM.js.map +1 -0
  5. package/dist/{chunk-AKJGYZME.js → chunk-A6AHJCEK.js} +67 -832
  6. package/dist/chunk-A6AHJCEK.js.map +1 -0
  7. package/dist/{chunk-3D2G5NBI.js → chunk-ASTNK6WZ.js} +2 -2
  8. package/dist/{chunk-VNXZVOPN.js → chunk-B7C6NBBQ.js} +929 -1
  9. package/dist/chunk-B7C6NBBQ.js.map +1 -0
  10. package/dist/chunk-FFXAOK4A.js +39 -0
  11. package/dist/chunk-FFXAOK4A.js.map +1 -0
  12. package/dist/{chunk-EQLBYW42.js → chunk-GSIPTCQH.js} +9 -1
  13. package/dist/chunk-GSIPTCQH.js.map +1 -0
  14. package/dist/collab.cjs +170 -2
  15. package/dist/collab.cjs.map +1 -1
  16. package/dist/collab.d.cts +1 -1
  17. package/dist/collab.d.ts +1 -1
  18. package/dist/collab.js +3 -3
  19. package/dist/index.cjs +1204 -540
  20. package/dist/index.cjs.map +1 -1
  21. package/dist/index.css +313 -0
  22. package/dist/index.css.map +1 -1
  23. package/dist/index.d.cts +2 -2
  24. package/dist/index.d.ts +2 -2
  25. package/dist/index.js +871 -494
  26. package/dist/index.js.map +1 -1
  27. package/dist/kinds.d.cts +1 -1
  28. package/dist/kinds.d.ts +1 -1
  29. package/dist/memory.cjs +3 -2
  30. package/dist/memory.cjs.map +1 -1
  31. package/dist/memory.d.cts +1 -1
  32. package/dist/memory.d.ts +1 -1
  33. package/dist/memory.js +3 -2
  34. package/dist/memory.js.map +1 -1
  35. package/dist/{types-BUO0OzOl.d.cts → types-CHmV8GLx.d.cts} +1 -0
  36. package/dist/{types-BUO0OzOl.d.ts → types-CHmV8GLx.d.ts} +1 -0
  37. package/package.json +1 -1
  38. package/dist/TextEditor-5S7FSLIZ.js.map +0 -1
  39. package/dist/chunk-AKJGYZME.js.map +0 -1
  40. package/dist/chunk-EQLBYW42.js.map +0 -1
  41. package/dist/chunk-VNXZVOPN.js.map +0 -1
  42. /package/dist/{Compare-M57FG4R3.js.map → Compare-RHAUAKUJ.js.map} +0 -0
  43. /package/dist/{SheetView-OEKOHMKW.js.map → SheetView-SBLAFGTL.js.map} +0 -0
  44. /package/dist/{chunk-3D2G5NBI.js.map → chunk-ASTNK6WZ.js.map} +0 -0
package/dist/kinds.d.cts CHANGED
@@ -1,4 +1,4 @@
1
- import { b as DocumentKind } from './types-BUO0OzOl.cjs';
1
+ import { b as DocumentKind } from './types-CHmV8GLx.cjs';
2
2
 
3
3
  declare const kinds: DocumentKind[];
4
4
  declare function kindOf(name: string, mimeType?: string | null): DocumentKind | null;
package/dist/kinds.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { b as DocumentKind } from './types-BUO0OzOl.js';
1
+ import { b as DocumentKind } from './types-CHmV8GLx.js';
2
2
 
3
3
  declare const kinds: DocumentKind[];
4
4
  declare function kindOf(name: string, mimeType?: string | null): DocumentKind | null;
package/dist/memory.cjs CHANGED
@@ -178,8 +178,9 @@ function memoryHost({ me, spaces, files, collab, people = [] }) {
178
178
  },
179
179
  ...spaces.length ? {
180
180
  createIn: `${spaces[0].name} / Documents`,
181
- create: async ({ name, bytes }) => {
182
- const file = { id: `new-${files.length + 1}`, spaceId: spaces[0].id, name, folder: "Documents", bytes, updatedAt: (/* @__PURE__ */ new Date()).toISOString() };
181
+ create: async ({ name, bytes, near }) => {
182
+ const by = near ? find(near) : null;
183
+ const file = { id: `new-${files.length + 1}`, spaceId: by?.spaceId ?? spaces[0].id, name, folder: by ? by.folder : "Documents", bytes, updatedAt: (/* @__PURE__ */ new Date()).toISOString() };
183
184
  files.push(file);
184
185
  return summary(file);
185
186
  }
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/memory.ts","../src/kinds.ts"],"sourcesContent":["import { kindOf } from './kinds';\nimport type { Comment, DocumentsHost, Person, Rights, Signature, Space } from './types';\n\ntype Bytes = ArrayBuffer | string;\n\nexport type MemoryFile = {\n id: string;\n spaceId: string;\n name: string;\n folder?: string;\n bytes: Bytes;\n version?: string;\n note?: string;\n updatedAt?: string;\n rights?: Partial<Rights>;\n versions?: { id: string; createdAt: string; bytes: Bytes; note?: string }[];\n signatures?: Signature[];\n comments?: Comment[];\n};\n\nconst mimes = { pdf: 'application/pdf', docx: 'application/vnd.openxmlformats-officedocument.wordprocessingml.document', md: 'text/markdown' };\n\nconst encode = (bytes: Bytes) => typeof bytes === 'string' ? new TextEncoder().encode(bytes).buffer as ArrayBuffer : bytes;\n\nexport function memoryHost({ me, spaces, files, collab, people = [] }: { me: Person; spaces: Space[]; files: MemoryFile[]; collab?: string; people?: Person[] }): DocumentsHost {\n const find = (id: string) => {\n const file = files.find(item => item.id === id);\n if (!file) throw new Error('document not found');\n return file;\n };\n const own = (file: MemoryFile, commentId: string) => {\n const found = file.comments?.find(c => c.id === commentId);\n if (!found || found.author.id !== me.id) throw new Error('only the author changes a comment');\n return found;\n };\n const summary = (file: MemoryFile) => ({\n id: file.id, spaceId: file.spaceId, name: file.name, kind: kindOf(file.name)!, size: encode(file.bytes).byteLength,\n updatedAt: file.updatedAt ?? '2026-10-19T09:00:00Z', updatedBy: me, createdAt: '2026-10-01T09:00:00Z', createdBy: me, folder: file.folder ?? null,\n });\n const archive = (file: MemoryFile, bytes: Bytes, note?: string) => {\n const versions = [{ id: file.version ?? `v${(file.versions?.length ?? 0) + 1}`, createdAt: file.updatedAt ?? '2026-10-19T09:00:00Z', bytes: file.bytes, note: file.note }, ...(file.versions ?? [])];\n const version = `v${versions.length + 1}`;\n Object.assign(file, { versions, version, bytes, note, updatedAt: new Date().toISOString() });\n return version;\n };\n return {\n me,\n ...(collab ? { collab: { url: `memory:${collab}`, token: async () => me.id } } : {}),\n spaces: async () => spaces,\n documents: async spaceId => files.filter(file => file.spaceId === spaceId && kindOf(file.name)).map(summary),\n document: async id => ({ ...summary(find(id)), rights: { view: true, comment: true, edit: true, ...find(id).rights }, live: !!collab }),\n versions: async id => {\n const file = find(id);\n return [\n { id: file.version ?? 'current', createdAt: summary(file).updatedAt, size: summary(file).size, author: me, note: file.note ?? null, current: true },\n ...(file.versions ?? []).map(v => ({ id: v.id, createdAt: v.createdAt, size: encode(v.bytes).byteLength, author: me, note: v.note ?? null, current: false })),\n ];\n },\n content: async (id, versionId) => {\n const file = find(id);\n const old = versionId && versionId !== 'current' && versionId !== file.version ? file.versions?.find(v => v.id === versionId) : undefined;\n return encode(old ? old.bytes : file.bytes);\n },\n restore: async (id, versionId) => {\n const file = find(id);\n const old = file.versions?.find(v => v.id === versionId);\n if (!old) throw new Error('version not found');\n archive(file, old.bytes);\n },\n save: async (id, bytes, note) => ({ versionId: archive(find(id), bytes, note) }),\n signatures: async id => [...(find(id).signatures ?? [])].reverse(),\n sign: async (id, entry) => {\n const file = find(id);\n const signature = { id: `s${(file.signatures?.length ?? 0) + 1}`, signer: me, signedAt: new Date().toISOString(), ...entry };\n file.signatures = [...(file.signatures ?? []), signature];\n return signature;\n },\n comments: async id => [...(find(id).comments ?? [])],\n people: async () => [me, ...people],\n comment: async (id, entry) => {\n const file = find(id);\n let n = (file.comments?.length ?? 0) + 1;\n while (file.comments?.some(c => c.id === `c${n}`)) n++;\n const made: Comment = { id: `c${n}`, documentId: id, author: me, body: entry.body, createdAt: new Date().toISOString(), quote: entry.quote, replyTo: entry.replyTo, resolved: false,\n assignee: people.find(p => p.id === entry.assignee) ?? null };\n file.comments = [...(file.comments ?? []), made];\n return made;\n },\n resolveComment: async (id, commentId, resolved) => {\n const file = find(id);\n file.comments = (file.comments ?? []).map(c => c.id === commentId ? { ...c, resolved } : c);\n },\n editComment: async (id, commentId, body) => {\n const file = find(id);\n const mine = own(file, commentId);\n const edited = { ...mine, body };\n file.comments = file.comments!.map(c => c === mine ? edited : c);\n return edited;\n },\n deleteComment: async (id, commentId) => {\n const file = find(id);\n if (!file.comments?.find(c => c.id === commentId)?.author.id.startsWith('guest:')) own(file, commentId);\n file.comments = file.comments!.filter(c => c.id !== commentId && c.replyTo !== commentId);\n },\n rename: async (id, name) => { find(id).name = name; },\n href: id => `https://docs.test/${id}`,\n remove: async id => { files.splice(files.indexOf(find(id)), 1); },\n templates: async () => files.filter(file => file.folder === 'Templates').map(summary),\n saveTemplate: async id => {\n const from = find(id);\n const file = { id: `t${files.length + 1}`, spaceId: from.spaceId, name: from.name, folder: 'Templates', bytes: from.bytes, updatedAt: new Date().toISOString() };\n files.push(file);\n return summary(file);\n },\n search: async text => files.flatMap(file => {\n const body = typeof file.bytes === 'string' && /\\.(md|txt)$/.test(file.name) ? file.bytes.replace(/\\s+/g, ' ') : '';\n const at = body.toLocaleLowerCase().indexOf(text.toLocaleLowerCase());\n return at < 0 ? [] : [{ id: file.id, excerpt: `${body.slice(Math.max(0, at - 30), at)}«${body.slice(at, at + text.length)}»${body.slice(at + text.length, at + text.length + 40)}` }];\n }),\n exportAs: async (id, format) => {\n const file = find(id);\n if ((format === 'md' ? 'markdown' : format) !== kindOf(file.name)) throw new Error('this format needs a converter on the host');\n return new Blob([encode(file.bytes)], { type: mimes[format] });\n },\n ...(spaces.length ? {\n createIn: `${spaces[0].name} / Documents`,\n create: async ({ name, bytes }: { name: string; bytes: ArrayBuffer }) => {\n const file = { id: `new-${files.length + 1}`, spaceId: spaces[0].id, name, folder: 'Documents', bytes, updatedAt: new Date().toISOString() };\n files.push(file);\n return summary(file);\n },\n } : {}),\n };\n}\n","import type { DocumentKind } from './types';\n\nconst byExtension: Record<string, DocumentKind> = {\n docx: 'docx', md: 'markdown', markdown: 'markdown', pdf: 'pdf', xlsx: 'sheet', csv: 'sheet', xls: 'sheet', ods: 'sheet', tsv: 'sheet', html: 'slides', htm: 'slides',\n};\n\nconst byMime: Record<string, DocumentKind> = {\n 'application/vnd.openxmlformats-officedocument.wordprocessingml.document': 'docx',\n 'text/markdown': 'markdown',\n 'application/pdf': 'pdf',\n 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet': 'sheet',\n 'text/csv': 'sheet',\n 'text/html': 'slides',\n};\n\nexport const kinds: DocumentKind[] = ['docx', 'markdown', 'pdf', 'sheet', 'slides'];\n\nexport function kindOf(name: string, mimeType?: string | null): DocumentKind | null {\n const extension = name.includes('.') ? name.split('.').pop()!.toLowerCase() : '';\n return byExtension[extension] ?? (mimeType ? byMime[mimeType.split(';')[0].trim().toLowerCase()] : undefined) ?? null;\n}\n\nexport function readable(name: string, mimeType?: string | null): DocumentKind | null {\n const kind = kindOf(name, mimeType);\n return kind !== 'sheet' || /\\.(xlsx|csv)$/i.test(name) || /spreadsheetml|text\\/csv/.test(mimeType ?? '') ? kind : null;\n}\n\nexport function matches(doc: { name: string; kind: DocumentKind }, query: string, picked: DocumentKind[]) {\n const words = query.toLocaleLowerCase().split(/\\s+/).filter(Boolean);\n return (!picked.length || picked.includes(doc.kind)) && words.every(word => doc.name.toLocaleLowerCase().includes(word));\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../src/memory.ts","../src/kinds.ts"],"sourcesContent":["import { kindOf } from './kinds';\nimport type { Comment, DocumentsHost, Person, Rights, Signature, Space } from './types';\n\ntype Bytes = ArrayBuffer | string;\n\nexport type MemoryFile = {\n id: string;\n spaceId: string;\n name: string;\n folder?: string;\n bytes: Bytes;\n version?: string;\n note?: string;\n updatedAt?: string;\n rights?: Partial<Rights>;\n versions?: { id: string; createdAt: string; bytes: Bytes; note?: string }[];\n signatures?: Signature[];\n comments?: Comment[];\n};\n\nconst mimes = { pdf: 'application/pdf', docx: 'application/vnd.openxmlformats-officedocument.wordprocessingml.document', md: 'text/markdown' };\n\nconst encode = (bytes: Bytes) => typeof bytes === 'string' ? new TextEncoder().encode(bytes).buffer as ArrayBuffer : bytes;\n\nexport function memoryHost({ me, spaces, files, collab, people = [] }: { me: Person; spaces: Space[]; files: MemoryFile[]; collab?: string; people?: Person[] }): DocumentsHost {\n const find = (id: string) => {\n const file = files.find(item => item.id === id);\n if (!file) throw new Error('document not found');\n return file;\n };\n const own = (file: MemoryFile, commentId: string) => {\n const found = file.comments?.find(c => c.id === commentId);\n if (!found || found.author.id !== me.id) throw new Error('only the author changes a comment');\n return found;\n };\n const summary = (file: MemoryFile) => ({\n id: file.id, spaceId: file.spaceId, name: file.name, kind: kindOf(file.name)!, size: encode(file.bytes).byteLength,\n updatedAt: file.updatedAt ?? '2026-10-19T09:00:00Z', updatedBy: me, createdAt: '2026-10-01T09:00:00Z', createdBy: me, folder: file.folder ?? null,\n });\n const archive = (file: MemoryFile, bytes: Bytes, note?: string) => {\n const versions = [{ id: file.version ?? `v${(file.versions?.length ?? 0) + 1}`, createdAt: file.updatedAt ?? '2026-10-19T09:00:00Z', bytes: file.bytes, note: file.note }, ...(file.versions ?? [])];\n const version = `v${versions.length + 1}`;\n Object.assign(file, { versions, version, bytes, note, updatedAt: new Date().toISOString() });\n return version;\n };\n return {\n me,\n ...(collab ? { collab: { url: `memory:${collab}`, token: async () => me.id } } : {}),\n spaces: async () => spaces,\n documents: async spaceId => files.filter(file => file.spaceId === spaceId && kindOf(file.name)).map(summary),\n document: async id => ({ ...summary(find(id)), rights: { view: true, comment: true, edit: true, ...find(id).rights }, live: !!collab }),\n versions: async id => {\n const file = find(id);\n return [\n { id: file.version ?? 'current', createdAt: summary(file).updatedAt, size: summary(file).size, author: me, note: file.note ?? null, current: true },\n ...(file.versions ?? []).map(v => ({ id: v.id, createdAt: v.createdAt, size: encode(v.bytes).byteLength, author: me, note: v.note ?? null, current: false })),\n ];\n },\n content: async (id, versionId) => {\n const file = find(id);\n const old = versionId && versionId !== 'current' && versionId !== file.version ? file.versions?.find(v => v.id === versionId) : undefined;\n return encode(old ? old.bytes : file.bytes);\n },\n restore: async (id, versionId) => {\n const file = find(id);\n const old = file.versions?.find(v => v.id === versionId);\n if (!old) throw new Error('version not found');\n archive(file, old.bytes);\n },\n save: async (id, bytes, note) => ({ versionId: archive(find(id), bytes, note) }),\n signatures: async id => [...(find(id).signatures ?? [])].reverse(),\n sign: async (id, entry) => {\n const file = find(id);\n const signature = { id: `s${(file.signatures?.length ?? 0) + 1}`, signer: me, signedAt: new Date().toISOString(), ...entry };\n file.signatures = [...(file.signatures ?? []), signature];\n return signature;\n },\n comments: async id => [...(find(id).comments ?? [])],\n people: async () => [me, ...people],\n comment: async (id, entry) => {\n const file = find(id);\n let n = (file.comments?.length ?? 0) + 1;\n while (file.comments?.some(c => c.id === `c${n}`)) n++;\n const made: Comment = { id: `c${n}`, documentId: id, author: me, body: entry.body, createdAt: new Date().toISOString(), quote: entry.quote, replyTo: entry.replyTo, resolved: false,\n assignee: people.find(p => p.id === entry.assignee) ?? null };\n file.comments = [...(file.comments ?? []), made];\n return made;\n },\n resolveComment: async (id, commentId, resolved) => {\n const file = find(id);\n file.comments = (file.comments ?? []).map(c => c.id === commentId ? { ...c, resolved } : c);\n },\n editComment: async (id, commentId, body) => {\n const file = find(id);\n const mine = own(file, commentId);\n const edited = { ...mine, body };\n file.comments = file.comments!.map(c => c === mine ? edited : c);\n return edited;\n },\n deleteComment: async (id, commentId) => {\n const file = find(id);\n if (!file.comments?.find(c => c.id === commentId)?.author.id.startsWith('guest:')) own(file, commentId);\n file.comments = file.comments!.filter(c => c.id !== commentId && c.replyTo !== commentId);\n },\n rename: async (id, name) => { find(id).name = name; },\n href: id => `https://docs.test/${id}`,\n remove: async id => { files.splice(files.indexOf(find(id)), 1); },\n templates: async () => files.filter(file => file.folder === 'Templates').map(summary),\n saveTemplate: async id => {\n const from = find(id);\n const file = { id: `t${files.length + 1}`, spaceId: from.spaceId, name: from.name, folder: 'Templates', bytes: from.bytes, updatedAt: new Date().toISOString() };\n files.push(file);\n return summary(file);\n },\n search: async text => files.flatMap(file => {\n const body = typeof file.bytes === 'string' && /\\.(md|txt)$/.test(file.name) ? file.bytes.replace(/\\s+/g, ' ') : '';\n const at = body.toLocaleLowerCase().indexOf(text.toLocaleLowerCase());\n return at < 0 ? [] : [{ id: file.id, excerpt: `${body.slice(Math.max(0, at - 30), at)}«${body.slice(at, at + text.length)}»${body.slice(at + text.length, at + text.length + 40)}` }];\n }),\n exportAs: async (id, format) => {\n const file = find(id);\n if ((format === 'md' ? 'markdown' : format) !== kindOf(file.name)) throw new Error('this format needs a converter on the host');\n return new Blob([encode(file.bytes)], { type: mimes[format] });\n },\n ...(spaces.length ? {\n createIn: `${spaces[0].name} / Documents`,\n create: async ({ name, bytes, near }: { name: string; bytes: ArrayBuffer; near?: string }) => {\n const by = near ? find(near) : null;\n const file = { id: `new-${files.length + 1}`, spaceId: by?.spaceId ?? spaces[0].id, name, folder: by ? by.folder : 'Documents', bytes, updatedAt: new Date().toISOString() };\n files.push(file);\n return summary(file);\n },\n } : {}),\n };\n}\n","import type { DocumentKind } from './types';\n\nconst byExtension: Record<string, DocumentKind> = {\n docx: 'docx', md: 'markdown', markdown: 'markdown', pdf: 'pdf', xlsx: 'sheet', csv: 'sheet', xls: 'sheet', ods: 'sheet', tsv: 'sheet', html: 'slides', htm: 'slides',\n};\n\nconst byMime: Record<string, DocumentKind> = {\n 'application/vnd.openxmlformats-officedocument.wordprocessingml.document': 'docx',\n 'text/markdown': 'markdown',\n 'application/pdf': 'pdf',\n 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet': 'sheet',\n 'text/csv': 'sheet',\n 'text/html': 'slides',\n};\n\nexport const kinds: DocumentKind[] = ['docx', 'markdown', 'pdf', 'sheet', 'slides'];\n\nexport function kindOf(name: string, mimeType?: string | null): DocumentKind | null {\n const extension = name.includes('.') ? name.split('.').pop()!.toLowerCase() : '';\n return byExtension[extension] ?? (mimeType ? byMime[mimeType.split(';')[0].trim().toLowerCase()] : undefined) ?? null;\n}\n\nexport function readable(name: string, mimeType?: string | null): DocumentKind | null {\n const kind = kindOf(name, mimeType);\n return kind !== 'sheet' || /\\.(xlsx|csv)$/i.test(name) || /spreadsheetml|text\\/csv/.test(mimeType ?? '') ? kind : null;\n}\n\nexport function matches(doc: { name: string; kind: DocumentKind }, query: string, picked: DocumentKind[]) {\n const words = query.toLocaleLowerCase().split(/\\s+/).filter(Boolean);\n return (!picked.length || picked.includes(doc.kind)) && words.every(word => doc.name.toLocaleLowerCase().includes(word));\n}\n"],"mappings":"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","names":[]}
package/dist/memory.d.cts CHANGED
@@ -1,4 +1,4 @@
1
- import { R as Rights, S as Signature, C as Comment, h as Person, j as Space, D as DocumentsHost } from './types-BUO0OzOl.cjs';
1
+ import { R as Rights, S as Signature, C as Comment, h as Person, j as Space, D as DocumentsHost } from './types-CHmV8GLx.cjs';
2
2
 
3
3
  type Bytes = ArrayBuffer | string;
4
4
  type MemoryFile = {
package/dist/memory.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { R as Rights, S as Signature, C as Comment, h as Person, j as Space, D as DocumentsHost } from './types-BUO0OzOl.js';
1
+ import { R as Rights, S as Signature, C as Comment, h as Person, j as Space, D as DocumentsHost } from './types-CHmV8GLx.js';
2
2
 
3
3
  type Bytes = ArrayBuffer | string;
4
4
  type MemoryFile = {
package/dist/memory.js CHANGED
@@ -129,8 +129,9 @@ function memoryHost({ me, spaces, files, collab, people = [] }) {
129
129
  },
130
130
  ...spaces.length ? {
131
131
  createIn: `${spaces[0].name} / Documents`,
132
- create: async ({ name, bytes }) => {
133
- const file = { id: `new-${files.length + 1}`, spaceId: spaces[0].id, name, folder: "Documents", bytes, updatedAt: (/* @__PURE__ */ new Date()).toISOString() };
132
+ create: async ({ name, bytes, near }) => {
133
+ const by = near ? find(near) : null;
134
+ const file = { id: `new-${files.length + 1}`, spaceId: by?.spaceId ?? spaces[0].id, name, folder: by ? by.folder : "Documents", bytes, updatedAt: (/* @__PURE__ */ new Date()).toISOString() };
134
135
  files.push(file);
135
136
  return summary(file);
136
137
  }
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/memory.ts"],"sourcesContent":["import { kindOf } from './kinds';\nimport type { Comment, DocumentsHost, Person, Rights, Signature, Space } from './types';\n\ntype Bytes = ArrayBuffer | string;\n\nexport type MemoryFile = {\n id: string;\n spaceId: string;\n name: string;\n folder?: string;\n bytes: Bytes;\n version?: string;\n note?: string;\n updatedAt?: string;\n rights?: Partial<Rights>;\n versions?: { id: string; createdAt: string; bytes: Bytes; note?: string }[];\n signatures?: Signature[];\n comments?: Comment[];\n};\n\nconst mimes = { pdf: 'application/pdf', docx: 'application/vnd.openxmlformats-officedocument.wordprocessingml.document', md: 'text/markdown' };\n\nconst encode = (bytes: Bytes) => typeof bytes === 'string' ? new TextEncoder().encode(bytes).buffer as ArrayBuffer : bytes;\n\nexport function memoryHost({ me, spaces, files, collab, people = [] }: { me: Person; spaces: Space[]; files: MemoryFile[]; collab?: string; people?: Person[] }): DocumentsHost {\n const find = (id: string) => {\n const file = files.find(item => item.id === id);\n if (!file) throw new Error('document not found');\n return file;\n };\n const own = (file: MemoryFile, commentId: string) => {\n const found = file.comments?.find(c => c.id === commentId);\n if (!found || found.author.id !== me.id) throw new Error('only the author changes a comment');\n return found;\n };\n const summary = (file: MemoryFile) => ({\n id: file.id, spaceId: file.spaceId, name: file.name, kind: kindOf(file.name)!, size: encode(file.bytes).byteLength,\n updatedAt: file.updatedAt ?? '2026-10-19T09:00:00Z', updatedBy: me, createdAt: '2026-10-01T09:00:00Z', createdBy: me, folder: file.folder ?? null,\n });\n const archive = (file: MemoryFile, bytes: Bytes, note?: string) => {\n const versions = [{ id: file.version ?? `v${(file.versions?.length ?? 0) + 1}`, createdAt: file.updatedAt ?? '2026-10-19T09:00:00Z', bytes: file.bytes, note: file.note }, ...(file.versions ?? [])];\n const version = `v${versions.length + 1}`;\n Object.assign(file, { versions, version, bytes, note, updatedAt: new Date().toISOString() });\n return version;\n };\n return {\n me,\n ...(collab ? { collab: { url: `memory:${collab}`, token: async () => me.id } } : {}),\n spaces: async () => spaces,\n documents: async spaceId => files.filter(file => file.spaceId === spaceId && kindOf(file.name)).map(summary),\n document: async id => ({ ...summary(find(id)), rights: { view: true, comment: true, edit: true, ...find(id).rights }, live: !!collab }),\n versions: async id => {\n const file = find(id);\n return [\n { id: file.version ?? 'current', createdAt: summary(file).updatedAt, size: summary(file).size, author: me, note: file.note ?? null, current: true },\n ...(file.versions ?? []).map(v => ({ id: v.id, createdAt: v.createdAt, size: encode(v.bytes).byteLength, author: me, note: v.note ?? null, current: false })),\n ];\n },\n content: async (id, versionId) => {\n const file = find(id);\n const old = versionId && versionId !== 'current' && versionId !== file.version ? file.versions?.find(v => v.id === versionId) : undefined;\n return encode(old ? old.bytes : file.bytes);\n },\n restore: async (id, versionId) => {\n const file = find(id);\n const old = file.versions?.find(v => v.id === versionId);\n if (!old) throw new Error('version not found');\n archive(file, old.bytes);\n },\n save: async (id, bytes, note) => ({ versionId: archive(find(id), bytes, note) }),\n signatures: async id => [...(find(id).signatures ?? [])].reverse(),\n sign: async (id, entry) => {\n const file = find(id);\n const signature = { id: `s${(file.signatures?.length ?? 0) + 1}`, signer: me, signedAt: new Date().toISOString(), ...entry };\n file.signatures = [...(file.signatures ?? []), signature];\n return signature;\n },\n comments: async id => [...(find(id).comments ?? [])],\n people: async () => [me, ...people],\n comment: async (id, entry) => {\n const file = find(id);\n let n = (file.comments?.length ?? 0) + 1;\n while (file.comments?.some(c => c.id === `c${n}`)) n++;\n const made: Comment = { id: `c${n}`, documentId: id, author: me, body: entry.body, createdAt: new Date().toISOString(), quote: entry.quote, replyTo: entry.replyTo, resolved: false,\n assignee: people.find(p => p.id === entry.assignee) ?? null };\n file.comments = [...(file.comments ?? []), made];\n return made;\n },\n resolveComment: async (id, commentId, resolved) => {\n const file = find(id);\n file.comments = (file.comments ?? []).map(c => c.id === commentId ? { ...c, resolved } : c);\n },\n editComment: async (id, commentId, body) => {\n const file = find(id);\n const mine = own(file, commentId);\n const edited = { ...mine, body };\n file.comments = file.comments!.map(c => c === mine ? edited : c);\n return edited;\n },\n deleteComment: async (id, commentId) => {\n const file = find(id);\n if (!file.comments?.find(c => c.id === commentId)?.author.id.startsWith('guest:')) own(file, commentId);\n file.comments = file.comments!.filter(c => c.id !== commentId && c.replyTo !== commentId);\n },\n rename: async (id, name) => { find(id).name = name; },\n href: id => `https://docs.test/${id}`,\n remove: async id => { files.splice(files.indexOf(find(id)), 1); },\n templates: async () => files.filter(file => file.folder === 'Templates').map(summary),\n saveTemplate: async id => {\n const from = find(id);\n const file = { id: `t${files.length + 1}`, spaceId: from.spaceId, name: from.name, folder: 'Templates', bytes: from.bytes, updatedAt: new Date().toISOString() };\n files.push(file);\n return summary(file);\n },\n search: async text => files.flatMap(file => {\n const body = typeof file.bytes === 'string' && /\\.(md|txt)$/.test(file.name) ? file.bytes.replace(/\\s+/g, ' ') : '';\n const at = body.toLocaleLowerCase().indexOf(text.toLocaleLowerCase());\n return at < 0 ? [] : [{ id: file.id, excerpt: `${body.slice(Math.max(0, at - 30), at)}«${body.slice(at, at + text.length)}»${body.slice(at + text.length, at + text.length + 40)}` }];\n }),\n exportAs: async (id, format) => {\n const file = find(id);\n if ((format === 'md' ? 'markdown' : format) !== kindOf(file.name)) throw new Error('this format needs a converter on the host');\n return new Blob([encode(file.bytes)], { type: mimes[format] });\n },\n ...(spaces.length ? {\n createIn: `${spaces[0].name} / Documents`,\n create: async ({ name, bytes }: { name: string; bytes: ArrayBuffer }) => {\n const file = { id: `new-${files.length + 1}`, spaceId: spaces[0].id, name, folder: 'Documents', bytes, updatedAt: new Date().toISOString() };\n files.push(file);\n return summary(file);\n },\n } : {}),\n };\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../src/memory.ts"],"sourcesContent":["import { kindOf } from './kinds';\nimport type { Comment, DocumentsHost, Person, Rights, Signature, Space } from './types';\n\ntype Bytes = ArrayBuffer | string;\n\nexport type MemoryFile = {\n id: string;\n spaceId: string;\n name: string;\n folder?: string;\n bytes: Bytes;\n version?: string;\n note?: string;\n updatedAt?: string;\n rights?: Partial<Rights>;\n versions?: { id: string; createdAt: string; bytes: Bytes; note?: string }[];\n signatures?: Signature[];\n comments?: Comment[];\n};\n\nconst mimes = { pdf: 'application/pdf', docx: 'application/vnd.openxmlformats-officedocument.wordprocessingml.document', md: 'text/markdown' };\n\nconst encode = (bytes: Bytes) => typeof bytes === 'string' ? new TextEncoder().encode(bytes).buffer as ArrayBuffer : bytes;\n\nexport function memoryHost({ me, spaces, files, collab, people = [] }: { me: Person; spaces: Space[]; files: MemoryFile[]; collab?: string; people?: Person[] }): DocumentsHost {\n const find = (id: string) => {\n const file = files.find(item => item.id === id);\n if (!file) throw new Error('document not found');\n return file;\n };\n const own = (file: MemoryFile, commentId: string) => {\n const found = file.comments?.find(c => c.id === commentId);\n if (!found || found.author.id !== me.id) throw new Error('only the author changes a comment');\n return found;\n };\n const summary = (file: MemoryFile) => ({\n id: file.id, spaceId: file.spaceId, name: file.name, kind: kindOf(file.name)!, size: encode(file.bytes).byteLength,\n updatedAt: file.updatedAt ?? '2026-10-19T09:00:00Z', updatedBy: me, createdAt: '2026-10-01T09:00:00Z', createdBy: me, folder: file.folder ?? null,\n });\n const archive = (file: MemoryFile, bytes: Bytes, note?: string) => {\n const versions = [{ id: file.version ?? `v${(file.versions?.length ?? 0) + 1}`, createdAt: file.updatedAt ?? '2026-10-19T09:00:00Z', bytes: file.bytes, note: file.note }, ...(file.versions ?? [])];\n const version = `v${versions.length + 1}`;\n Object.assign(file, { versions, version, bytes, note, updatedAt: new Date().toISOString() });\n return version;\n };\n return {\n me,\n ...(collab ? { collab: { url: `memory:${collab}`, token: async () => me.id } } : {}),\n spaces: async () => spaces,\n documents: async spaceId => files.filter(file => file.spaceId === spaceId && kindOf(file.name)).map(summary),\n document: async id => ({ ...summary(find(id)), rights: { view: true, comment: true, edit: true, ...find(id).rights }, live: !!collab }),\n versions: async id => {\n const file = find(id);\n return [\n { id: file.version ?? 'current', createdAt: summary(file).updatedAt, size: summary(file).size, author: me, note: file.note ?? null, current: true },\n ...(file.versions ?? []).map(v => ({ id: v.id, createdAt: v.createdAt, size: encode(v.bytes).byteLength, author: me, note: v.note ?? null, current: false })),\n ];\n },\n content: async (id, versionId) => {\n const file = find(id);\n const old = versionId && versionId !== 'current' && versionId !== file.version ? file.versions?.find(v => v.id === versionId) : undefined;\n return encode(old ? old.bytes : file.bytes);\n },\n restore: async (id, versionId) => {\n const file = find(id);\n const old = file.versions?.find(v => v.id === versionId);\n if (!old) throw new Error('version not found');\n archive(file, old.bytes);\n },\n save: async (id, bytes, note) => ({ versionId: archive(find(id), bytes, note) }),\n signatures: async id => [...(find(id).signatures ?? [])].reverse(),\n sign: async (id, entry) => {\n const file = find(id);\n const signature = { id: `s${(file.signatures?.length ?? 0) + 1}`, signer: me, signedAt: new Date().toISOString(), ...entry };\n file.signatures = [...(file.signatures ?? []), signature];\n return signature;\n },\n comments: async id => [...(find(id).comments ?? [])],\n people: async () => [me, ...people],\n comment: async (id, entry) => {\n const file = find(id);\n let n = (file.comments?.length ?? 0) + 1;\n while (file.comments?.some(c => c.id === `c${n}`)) n++;\n const made: Comment = { id: `c${n}`, documentId: id, author: me, body: entry.body, createdAt: new Date().toISOString(), quote: entry.quote, replyTo: entry.replyTo, resolved: false,\n assignee: people.find(p => p.id === entry.assignee) ?? null };\n file.comments = [...(file.comments ?? []), made];\n return made;\n },\n resolveComment: async (id, commentId, resolved) => {\n const file = find(id);\n file.comments = (file.comments ?? []).map(c => c.id === commentId ? { ...c, resolved } : c);\n },\n editComment: async (id, commentId, body) => {\n const file = find(id);\n const mine = own(file, commentId);\n const edited = { ...mine, body };\n file.comments = file.comments!.map(c => c === mine ? edited : c);\n return edited;\n },\n deleteComment: async (id, commentId) => {\n const file = find(id);\n if (!file.comments?.find(c => c.id === commentId)?.author.id.startsWith('guest:')) own(file, commentId);\n file.comments = file.comments!.filter(c => c.id !== commentId && c.replyTo !== commentId);\n },\n rename: async (id, name) => { find(id).name = name; },\n href: id => `https://docs.test/${id}`,\n remove: async id => { files.splice(files.indexOf(find(id)), 1); },\n templates: async () => files.filter(file => file.folder === 'Templates').map(summary),\n saveTemplate: async id => {\n const from = find(id);\n const file = { id: `t${files.length + 1}`, spaceId: from.spaceId, name: from.name, folder: 'Templates', bytes: from.bytes, updatedAt: new Date().toISOString() };\n files.push(file);\n return summary(file);\n },\n search: async text => files.flatMap(file => {\n const body = typeof file.bytes === 'string' && /\\.(md|txt)$/.test(file.name) ? file.bytes.replace(/\\s+/g, ' ') : '';\n const at = body.toLocaleLowerCase().indexOf(text.toLocaleLowerCase());\n return at < 0 ? [] : [{ id: file.id, excerpt: `${body.slice(Math.max(0, at - 30), at)}«${body.slice(at, at + text.length)}»${body.slice(at + text.length, at + text.length + 40)}` }];\n }),\n exportAs: async (id, format) => {\n const file = find(id);\n if ((format === 'md' ? 'markdown' : format) !== kindOf(file.name)) throw new Error('this format needs a converter on the host');\n return new Blob([encode(file.bytes)], { type: mimes[format] });\n },\n ...(spaces.length ? {\n createIn: `${spaces[0].name} / Documents`,\n create: async ({ name, bytes, near }: { name: string; bytes: ArrayBuffer; near?: string }) => {\n const by = near ? find(near) : null;\n const file = { id: `new-${files.length + 1}`, spaceId: by?.spaceId ?? spaces[0].id, name, folder: by ? by.folder : 'Documents', bytes, updatedAt: new Date().toISOString() };\n files.push(file);\n return summary(file);\n },\n } : {}),\n };\n}\n"],"mappings":";;;;;;AAoBA,IAAM,QAAQ,EAAE,KAAK,mBAAmB,MAAM,2EAA2E,IAAI,gBAAgB;AAE7I,IAAM,SAAS,CAAC,UAAiB,OAAO,UAAU,WAAW,IAAI,YAAY,EAAE,OAAO,KAAK,EAAE,SAAwB;AAE9G,SAAS,WAAW,EAAE,IAAI,QAAQ,OAAO,QAAQ,SAAS,CAAC,EAAE,GAA4G;AAC9K,QAAM,OAAO,CAAC,OAAe;AAC3B,UAAM,OAAO,MAAM,KAAK,UAAQ,KAAK,OAAO,EAAE;AAC9C,QAAI,CAAC,KAAM,OAAM,IAAI,MAAM,oBAAoB;AAC/C,WAAO;AAAA,EACT;AACA,QAAM,MAAM,CAAC,MAAkB,cAAsB;AACnD,UAAM,QAAQ,KAAK,UAAU,KAAK,OAAK,EAAE,OAAO,SAAS;AACzD,QAAI,CAAC,SAAS,MAAM,OAAO,OAAO,GAAG,GAAI,OAAM,IAAI,MAAM,mCAAmC;AAC5F,WAAO;AAAA,EACT;AACA,QAAM,UAAU,CAAC,UAAsB;AAAA,IACrC,IAAI,KAAK;AAAA,IAAI,SAAS,KAAK;AAAA,IAAS,MAAM,KAAK;AAAA,IAAM,MAAM,OAAO,KAAK,IAAI;AAAA,IAAI,MAAM,OAAO,KAAK,KAAK,EAAE;AAAA,IACxG,WAAW,KAAK,aAAa;AAAA,IAAwB,WAAW;AAAA,IAAI,WAAW;AAAA,IAAwB,WAAW;AAAA,IAAI,QAAQ,KAAK,UAAU;AAAA,EAC/I;AACA,QAAM,UAAU,CAAC,MAAkB,OAAc,SAAkB;AACjE,UAAM,WAAW,CAAC,EAAE,IAAI,KAAK,WAAW,KAAK,KAAK,UAAU,UAAU,KAAK,CAAC,IAAI,WAAW,KAAK,aAAa,wBAAwB,OAAO,KAAK,OAAO,MAAM,KAAK,KAAK,GAAG,GAAI,KAAK,YAAY,CAAC,CAAE;AACnM,UAAM,UAAU,IAAI,SAAS,SAAS,CAAC;AACvC,WAAO,OAAO,MAAM,EAAE,UAAU,SAAS,OAAO,MAAM,YAAW,oBAAI,KAAK,GAAE,YAAY,EAAE,CAAC;AAC3F,WAAO;AAAA,EACT;AACA,SAAO;AAAA,IACL;AAAA,IACA,GAAI,SAAS,EAAE,QAAQ,EAAE,KAAK,UAAU,MAAM,IAAI,OAAO,YAAY,GAAG,GAAG,EAAE,IAAI,CAAC;AAAA,IAClF,QAAQ,YAAY;AAAA,IACpB,WAAW,OAAM,YAAW,MAAM,OAAO,UAAQ,KAAK,YAAY,WAAW,OAAO,KAAK,IAAI,CAAC,EAAE,IAAI,OAAO;AAAA,IAC3G,UAAU,OAAM,QAAO,EAAE,GAAG,QAAQ,KAAK,EAAE,CAAC,GAAG,QAAQ,EAAE,MAAM,MAAM,SAAS,MAAM,MAAM,MAAM,GAAG,KAAK,EAAE,EAAE,OAAO,GAAG,MAAM,CAAC,CAAC,OAAO;AAAA,IACrI,UAAU,OAAM,OAAM;AACpB,YAAM,OAAO,KAAK,EAAE;AACpB,aAAO;AAAA,QACL,EAAE,IAAI,KAAK,WAAW,WAAW,WAAW,QAAQ,IAAI,EAAE,WAAW,MAAM,QAAQ,IAAI,EAAE,MAAM,QAAQ,IAAI,MAAM,KAAK,QAAQ,MAAM,SAAS,KAAK;AAAA,QAClJ,IAAI,KAAK,YAAY,CAAC,GAAG,IAAI,QAAM,EAAE,IAAI,EAAE,IAAI,WAAW,EAAE,WAAW,MAAM,OAAO,EAAE,KAAK,EAAE,YAAY,QAAQ,IAAI,MAAM,EAAE,QAAQ,MAAM,SAAS,MAAM,EAAE;AAAA,MAC9J;AAAA,IACF;AAAA,IACA,SAAS,OAAO,IAAI,cAAc;AAChC,YAAM,OAAO,KAAK,EAAE;AACpB,YAAM,MAAM,aAAa,cAAc,aAAa,cAAc,KAAK,UAAU,KAAK,UAAU,KAAK,OAAK,EAAE,OAAO,SAAS,IAAI;AAChI,aAAO,OAAO,MAAM,IAAI,QAAQ,KAAK,KAAK;AAAA,IAC5C;AAAA,IACA,SAAS,OAAO,IAAI,cAAc;AAChC,YAAM,OAAO,KAAK,EAAE;AACpB,YAAM,MAAM,KAAK,UAAU,KAAK,OAAK,EAAE,OAAO,SAAS;AACvD,UAAI,CAAC,IAAK,OAAM,IAAI,MAAM,mBAAmB;AAC7C,cAAQ,MAAM,IAAI,KAAK;AAAA,IACzB;AAAA,IACA,MAAM,OAAO,IAAI,OAAO,UAAU,EAAE,WAAW,QAAQ,KAAK,EAAE,GAAG,OAAO,IAAI,EAAE;AAAA,IAC9E,YAAY,OAAM,OAAM,CAAC,GAAI,KAAK,EAAE,EAAE,cAAc,CAAC,CAAE,EAAE,QAAQ;AAAA,IACjE,MAAM,OAAO,IAAI,UAAU;AACzB,YAAM,OAAO,KAAK,EAAE;AACpB,YAAM,YAAY,EAAE,IAAI,KAAK,KAAK,YAAY,UAAU,KAAK,CAAC,IAAI,QAAQ,IAAI,WAAU,oBAAI,KAAK,GAAE,YAAY,GAAG,GAAG,MAAM;AAC3H,WAAK,aAAa,CAAC,GAAI,KAAK,cAAc,CAAC,GAAI,SAAS;AACxD,aAAO;AAAA,IACT;AAAA,IACA,UAAU,OAAM,OAAM,CAAC,GAAI,KAAK,EAAE,EAAE,YAAY,CAAC,CAAE;AAAA,IACnD,QAAQ,YAAY,CAAC,IAAI,GAAG,MAAM;AAAA,IAClC,SAAS,OAAO,IAAI,UAAU;AAC5B,YAAM,OAAO,KAAK,EAAE;AACpB,UAAI,KAAK,KAAK,UAAU,UAAU,KAAK;AACvC,aAAO,KAAK,UAAU,KAAK,OAAK,EAAE,OAAO,IAAI,CAAC,EAAE,EAAG;AACnD,YAAM,OAAgB;AAAA,QAAE,IAAI,IAAI,CAAC;AAAA,QAAI,YAAY;AAAA,QAAI,QAAQ;AAAA,QAAI,MAAM,MAAM;AAAA,QAAM,YAAW,oBAAI,KAAK,GAAE,YAAY;AAAA,QAAG,OAAO,MAAM;AAAA,QAAO,SAAS,MAAM;AAAA,QAAS,UAAU;AAAA,QAC5K,UAAU,OAAO,KAAK,OAAK,EAAE,OAAO,MAAM,QAAQ,KAAK;AAAA,MAAK;AAC9D,WAAK,WAAW,CAAC,GAAI,KAAK,YAAY,CAAC,GAAI,IAAI;AAC/C,aAAO;AAAA,IACT;AAAA,IACA,gBAAgB,OAAO,IAAI,WAAW,aAAa;AACjD,YAAM,OAAO,KAAK,EAAE;AACpB,WAAK,YAAY,KAAK,YAAY,CAAC,GAAG,IAAI,OAAK,EAAE,OAAO,YAAY,EAAE,GAAG,GAAG,SAAS,IAAI,CAAC;AAAA,IAC5F;AAAA,IACA,aAAa,OAAO,IAAI,WAAW,SAAS;AAC1C,YAAM,OAAO,KAAK,EAAE;AACpB,YAAM,OAAO,IAAI,MAAM,SAAS;AAChC,YAAM,SAAS,EAAE,GAAG,MAAM,KAAK;AAC/B,WAAK,WAAW,KAAK,SAAU,IAAI,OAAK,MAAM,OAAO,SAAS,CAAC;AAC/D,aAAO;AAAA,IACT;AAAA,IACA,eAAe,OAAO,IAAI,cAAc;AACtC,YAAM,OAAO,KAAK,EAAE;AACpB,UAAI,CAAC,KAAK,UAAU,KAAK,OAAK,EAAE,OAAO,SAAS,GAAG,OAAO,GAAG,WAAW,QAAQ,EAAG,KAAI,MAAM,SAAS;AACtG,WAAK,WAAW,KAAK,SAAU,OAAO,OAAK,EAAE,OAAO,aAAa,EAAE,YAAY,SAAS;AAAA,IAC1F;AAAA,IACA,QAAQ,OAAO,IAAI,SAAS;AAAE,WAAK,EAAE,EAAE,OAAO;AAAA,IAAM;AAAA,IACpD,MAAM,QAAM,qBAAqB,EAAE;AAAA,IACnC,QAAQ,OAAM,OAAM;AAAE,YAAM,OAAO,MAAM,QAAQ,KAAK,EAAE,CAAC,GAAG,CAAC;AAAA,IAAG;AAAA,IAChE,WAAW,YAAY,MAAM,OAAO,UAAQ,KAAK,WAAW,WAAW,EAAE,IAAI,OAAO;AAAA,IACpF,cAAc,OAAM,OAAM;AACxB,YAAM,OAAO,KAAK,EAAE;AACpB,YAAM,OAAO,EAAE,IAAI,IAAI,MAAM,SAAS,CAAC,IAAI,SAAS,KAAK,SAAS,MAAM,KAAK,MAAM,QAAQ,aAAa,OAAO,KAAK,OAAO,YAAW,oBAAI,KAAK,GAAE,YAAY,EAAE;AAC/J,YAAM,KAAK,IAAI;AACf,aAAO,QAAQ,IAAI;AAAA,IACrB;AAAA,IACA,QAAQ,OAAM,SAAQ,MAAM,QAAQ,UAAQ;AAC1C,YAAM,OAAO,OAAO,KAAK,UAAU,YAAY,cAAc,KAAK,KAAK,IAAI,IAAI,KAAK,MAAM,QAAQ,QAAQ,GAAG,IAAI;AACjH,YAAM,KAAK,KAAK,kBAAkB,EAAE,QAAQ,KAAK,kBAAkB,CAAC;AACpE,aAAO,KAAK,IAAI,CAAC,IAAI,CAAC,EAAE,IAAI,KAAK,IAAI,SAAS,GAAG,KAAK,MAAM,KAAK,IAAI,GAAG,KAAK,EAAE,GAAG,EAAE,CAAC,OAAI,KAAK,MAAM,IAAI,KAAK,KAAK,MAAM,CAAC,OAAI,KAAK,MAAM,KAAK,KAAK,QAAQ,KAAK,KAAK,SAAS,EAAE,CAAC,GAAG,CAAC;AAAA,IACtL,CAAC;AAAA,IACD,UAAU,OAAO,IAAI,WAAW;AAC9B,YAAM,OAAO,KAAK,EAAE;AACpB,WAAK,WAAW,OAAO,aAAa,YAAY,OAAO,KAAK,IAAI,EAAG,OAAM,IAAI,MAAM,2CAA2C;AAC9H,aAAO,IAAI,KAAK,CAAC,OAAO,KAAK,KAAK,CAAC,GAAG,EAAE,MAAM,MAAM,MAAM,EAAE,CAAC;AAAA,IAC/D;AAAA,IACA,GAAI,OAAO,SAAS;AAAA,MAClB,UAAU,GAAG,OAAO,CAAC,EAAE,IAAI;AAAA,MAC3B,QAAQ,OAAO,EAAE,MAAM,OAAO,KAAK,MAA2D;AAC5F,cAAM,KAAK,OAAO,KAAK,IAAI,IAAI;AAC/B,cAAM,OAAO,EAAE,IAAI,OAAO,MAAM,SAAS,CAAC,IAAI,SAAS,IAAI,WAAW,OAAO,CAAC,EAAE,IAAI,MAAM,QAAQ,KAAK,GAAG,SAAS,aAAa,OAAO,YAAW,oBAAI,KAAK,GAAE,YAAY,EAAE;AAC3K,cAAM,KAAK,IAAI;AACf,eAAO,QAAQ,IAAI;AAAA,MACrB;AAAA,IACF,IAAI,CAAC;AAAA,EACP;AACF;","names":[]}
@@ -167,6 +167,7 @@ interface DocumentsHost {
167
167
  name: string;
168
168
  bytes: ArrayBuffer;
169
169
  mimeType: string;
170
+ near?: string;
170
171
  }): Promise<DocumentSummary>;
171
172
  createIn?: string;
172
173
  links?(id: string, opts?: Fetch): Promise<GuestLink[]>;
@@ -167,6 +167,7 @@ interface DocumentsHost {
167
167
  name: string;
168
168
  bytes: ArrayBuffer;
169
169
  mimeType: string;
170
+ near?: string;
170
171
  }): Promise<DocumentSummary>;
171
172
  createIn?: string;
172
173
  links?(id: string, opts?: Fetch): Promise<GuestLink[]>;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@w100n/documents",
3
- "version": "0.16.4",
3
+ "version": "0.17.0",
4
4
  "description": "Documents workspace for Web100Now projects: DOCX, Markdown, PDF, slides and sheets",
5
5
  "license": "MIT",
6
6
  "type": "module",