@opengeni/artifact-tool 0.2.2
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/LICENSE +190 -0
- package/README.md +104 -0
- package/dist/bounded-zip.d.ts +28 -0
- package/dist/chunk-4BSENMAE.js +39 -0
- package/dist/chunk-4BSENMAE.js.map +1 -0
- package/dist/chunk-4FRFNNBM.js +276 -0
- package/dist/chunk-4FRFNNBM.js.map +1 -0
- package/dist/chunk-5XIA6KHZ.js +49 -0
- package/dist/chunk-5XIA6KHZ.js.map +1 -0
- package/dist/chunk-66CT2ZRP.js +2229 -0
- package/dist/chunk-66CT2ZRP.js.map +1 -0
- package/dist/chunk-72SYDU4O.js +319 -0
- package/dist/chunk-72SYDU4O.js.map +1 -0
- package/dist/chunk-B2ZJRZDA.js +279 -0
- package/dist/chunk-B2ZJRZDA.js.map +1 -0
- package/dist/chunk-DCTLTNPW.js +2458 -0
- package/dist/chunk-DCTLTNPW.js.map +1 -0
- package/dist/chunk-FGZM4FQ6.js +473 -0
- package/dist/chunk-FGZM4FQ6.js.map +1 -0
- package/dist/chunk-HTJBLBDE.js +591 -0
- package/dist/chunk-HTJBLBDE.js.map +1 -0
- package/dist/chunk-IYFXZQ34.js +5306 -0
- package/dist/chunk-IYFXZQ34.js.map +1 -0
- package/dist/chunk-J6N7IR44.js +172 -0
- package/dist/chunk-J6N7IR44.js.map +1 -0
- package/dist/chunk-N2IHNWBS.js +1002 -0
- package/dist/chunk-N2IHNWBS.js.map +1 -0
- package/dist/chunk-NAG44K67.js +549 -0
- package/dist/chunk-NAG44K67.js.map +1 -0
- package/dist/chunk-O24KTEGP.js +33 -0
- package/dist/chunk-O24KTEGP.js.map +1 -0
- package/dist/chunk-PI2AZVGK.js +2074 -0
- package/dist/chunk-PI2AZVGK.js.map +1 -0
- package/dist/chunk-Q2FFHEY7.js +40 -0
- package/dist/chunk-Q2FFHEY7.js.map +1 -0
- package/dist/chunk-RBGQADXA.js +57 -0
- package/dist/chunk-RBGQADXA.js.map +1 -0
- package/dist/chunk-U5G2BKM2.js +613 -0
- package/dist/chunk-U5G2BKM2.js.map +1 -0
- package/dist/chunk-VOJHMSM3.js +39 -0
- package/dist/chunk-VOJHMSM3.js.map +1 -0
- package/dist/chunk-VUNV25KB.js +16 -0
- package/dist/chunk-VUNV25KB.js.map +1 -0
- package/dist/chunk-XIFUNVBO.js +101 -0
- package/dist/chunk-XIFUNVBO.js.map +1 -0
- package/dist/chunk-ZCJYRJGB.js +489 -0
- package/dist/chunk-ZCJYRJGB.js.map +1 -0
- package/dist/chunk-ZZXPEE4S.js +2260 -0
- package/dist/chunk-ZZXPEE4S.js.map +1 -0
- package/dist/document-docx-api.d.ts +49 -0
- package/dist/document-docx-codec.d.ts +9 -0
- package/dist/document-docx-codec.js +4765 -0
- package/dist/document-docx-codec.js.map +1 -0
- package/dist/document-docx-import.d.ts +261 -0
- package/dist/document-docx-packer.d.ts +18 -0
- package/dist/document-docx-state.d.ts +12 -0
- package/dist/document-render.d.ts +3 -0
- package/dist/document-render.js +492 -0
- package/dist/document-render.js.map +1 -0
- package/dist/document.d.ts +432 -0
- package/dist/document.js +37 -0
- package/dist/document.js.map +1 -0
- package/dist/errors.d.ts +23 -0
- package/dist/file-blob.d.ts +11 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.js +186 -0
- package/dist/index.js.map +1 -0
- package/dist/inspection.d.ts +12 -0
- package/dist/kernel.d.ts +101 -0
- package/dist/lib-GQLPACFK.js +9746 -0
- package/dist/lib-GQLPACFK.js.map +1 -0
- package/dist/materializer-cli-entry.d.ts +2 -0
- package/dist/materializer-cli-entry.js +29 -0
- package/dist/materializer-cli-entry.js.map +1 -0
- package/dist/materializer-cli.d.ts +24 -0
- package/dist/materializer-cli.js +24 -0
- package/dist/materializer-cli.js.map +1 -0
- package/dist/native-raster.d.ts +10 -0
- package/dist/native.d.ts +129 -0
- package/dist/native.js +31 -0
- package/dist/native.js.map +1 -0
- package/dist/office-import.d.ts +48 -0
- package/dist/office-import.js +154 -0
- package/dist/office-import.js.map +1 -0
- package/dist/presentation-pptx-api.d.ts +60 -0
- package/dist/presentation-pptx-import.d.ts +5 -0
- package/dist/presentation-pptx-state-digest-765CZZED.js +10 -0
- package/dist/presentation-pptx-state-digest-765CZZED.js.map +1 -0
- package/dist/presentation-pptx-state-digest.d.ts +3 -0
- package/dist/presentation-pptx-state.d.ts +4 -0
- package/dist/presentation-pptx-xml.d.ts +29 -0
- package/dist/presentation-pptx.d.ts +5 -0
- package/dist/presentation-pptx.js +2365 -0
- package/dist/presentation-pptx.js.map +1 -0
- package/dist/presentation-render.d.ts +29 -0
- package/dist/presentation-render.js +375 -0
- package/dist/presentation-render.js.map +1 -0
- package/dist/presentation.d.ts +565 -0
- package/dist/presentation.js +71 -0
- package/dist/presentation.js.map +1 -0
- package/dist/production-composite.d.ts +68 -0
- package/dist/production-document.d.ts +2 -0
- package/dist/production-document.js +176 -0
- package/dist/production-document.js.map +1 -0
- package/dist/production-native-codecs.d.ts +94 -0
- package/dist/production-presentation.d.ts +2 -0
- package/dist/production-presentation.js +176 -0
- package/dist/production-presentation.js.map +1 -0
- package/dist/production-sha256.d.ts +2 -0
- package/dist/production-spreadsheet-native.d.ts +12 -0
- package/dist/production-spreadsheet.d.ts +2 -0
- package/dist/production-spreadsheet.js +176 -0
- package/dist/production-spreadsheet.js.map +1 -0
- package/dist/production.d.ts +96 -0
- package/dist/raster-image.d.ts +34 -0
- package/dist/reference.d.ts +17 -0
- package/dist/reference.js +574 -0
- package/dist/reference.js.map +1 -0
- package/dist/runtime-cli-entry.d.ts +2 -0
- package/dist/runtime-cli-entry.js +21 -0
- package/dist/runtime-cli-entry.js.map +1 -0
- package/dist/runtime-cli.d.ts +76 -0
- package/dist/runtime-cli.js +26 -0
- package/dist/runtime-cli.js.map +1 -0
- package/dist/runtime-development.d.ts +73 -0
- package/dist/runtime-development.js +30 -0
- package/dist/runtime-development.js.map +1 -0
- package/dist/runtime-receipt.d.ts +19 -0
- package/dist/runtime.d.ts +355 -0
- package/dist/runtime.js +42 -0
- package/dist/runtime.js.map +1 -0
- package/dist/snapshot.d.ts +26 -0
- package/dist/snapshot.js +61 -0
- package/dist/snapshot.js.map +1 -0
- package/dist/spreadsheet-address.d.ts +18 -0
- package/dist/spreadsheet-file.d.ts +17 -0
- package/dist/spreadsheet-formula.d.ts +67 -0
- package/dist/spreadsheet-image.d.ts +17 -0
- package/dist/spreadsheet-render.d.ts +5 -0
- package/dist/spreadsheet-render.js +752 -0
- package/dist/spreadsheet-render.js.map +1 -0
- package/dist/spreadsheet-types.d.ts +155 -0
- package/dist/spreadsheet-xlsx-api.d.ts +88 -0
- package/dist/spreadsheet-xlsx-codec.d.ts +16 -0
- package/dist/spreadsheet-xlsx-codec.js +16 -0
- package/dist/spreadsheet-xlsx-codec.js.map +1 -0
- package/dist/spreadsheet-xlsx-state.d.ts +16 -0
- package/dist/spreadsheet.d.ts +724 -0
- package/dist/spreadsheet.js +67 -0
- package/dist/spreadsheet.js.map +1 -0
- package/package.json +129 -0
- package/src/bounded-zip.ts +450 -0
- package/src/document-docx-api.ts +64 -0
- package/src/document-docx-codec.ts +2253 -0
- package/src/document-docx-import.ts +3814 -0
- package/src/document-docx-packer.ts +72 -0
- package/src/document-docx-state.ts +59 -0
- package/src/document-render.ts +615 -0
- package/src/document.ts +2800 -0
- package/src/errors.ts +45 -0
- package/src/file-blob.ts +43 -0
- package/src/index.ts +4 -0
- package/src/inspection.ts +50 -0
- package/src/kernel.ts +525 -0
- package/src/materializer-cli-entry.ts +11 -0
- package/src/materializer-cli.ts +743 -0
- package/src/native-raster.ts +141 -0
- package/src/native.ts +390 -0
- package/src/office-import.ts +243 -0
- package/src/presentation-pptx-api.ts +107 -0
- package/src/presentation-pptx-import.ts +2065 -0
- package/src/presentation-pptx-state-digest.ts +46 -0
- package/src/presentation-pptx-state.ts +18 -0
- package/src/presentation-pptx-xml.ts +473 -0
- package/src/presentation-pptx.ts +447 -0
- package/src/presentation-render.ts +532 -0
- package/src/presentation.ts +2599 -0
- package/src/production-composite.ts +805 -0
- package/src/production-document.ts +2 -0
- package/src/production-native-codecs.ts +1141 -0
- package/src/production-presentation.ts +2 -0
- package/src/production-sha256.ts +150 -0
- package/src/production-spreadsheet-native.ts +686 -0
- package/src/production-spreadsheet.ts +2 -0
- package/src/production.ts +1022 -0
- package/src/raster-image.ts +586 -0
- package/src/reference.ts +17 -0
- package/src/runtime-cli-entry.ts +13 -0
- package/src/runtime-cli.ts +670 -0
- package/src/runtime-development.ts +689 -0
- package/src/runtime-receipt.ts +169 -0
- package/src/runtime.ts +1463 -0
- package/src/snapshot.ts +88 -0
- package/src/spreadsheet-address.ts +90 -0
- package/src/spreadsheet-file.ts +71 -0
- package/src/spreadsheet-formula.ts +1212 -0
- package/src/spreadsheet-image.ts +242 -0
- package/src/spreadsheet-render.ts +985 -0
- package/src/spreadsheet-types.ts +171 -0
- package/src/spreadsheet-xlsx-api.ts +123 -0
- package/src/spreadsheet-xlsx-codec.ts +3063 -0
- package/src/spreadsheet-xlsx-state.ts +191 -0
- package/src/spreadsheet.ts +5195 -0
|
@@ -0,0 +1,1022 @@
|
|
|
1
|
+
import type { FileBlob } from "./file-blob";
|
|
2
|
+
import {
|
|
3
|
+
Document as ReferenceDocument,
|
|
4
|
+
DocumentBlockCollection,
|
|
5
|
+
DocumentCommentThread,
|
|
6
|
+
DocumentComments,
|
|
7
|
+
DocumentFile as ReferenceDocumentFile,
|
|
8
|
+
DocumentParagraph,
|
|
9
|
+
DocumentSection,
|
|
10
|
+
DocumentSections,
|
|
11
|
+
DocumentStory,
|
|
12
|
+
DocumentTable,
|
|
13
|
+
TrackedChanges,
|
|
14
|
+
type DocumentCreateOptions,
|
|
15
|
+
type SerializedDocument,
|
|
16
|
+
type SerializedDocumentBlock,
|
|
17
|
+
type DocumentTextStyle,
|
|
18
|
+
} from "./document";
|
|
19
|
+
import { DOCUMENT_LOSS_PRESERVATION } from "./document-docx-state";
|
|
20
|
+
import { NativeDocumentSession, NativePresentationSession } from "./native";
|
|
21
|
+
import {
|
|
22
|
+
Presentation as ReferencePresentation,
|
|
23
|
+
PresentationChart,
|
|
24
|
+
PresentationChartCollection,
|
|
25
|
+
PresentationFile as ReferencePresentationFile,
|
|
26
|
+
PresentationGroup,
|
|
27
|
+
PresentationGroupCollection,
|
|
28
|
+
PresentationImage,
|
|
29
|
+
PresentationImageCollection,
|
|
30
|
+
PresentationShape,
|
|
31
|
+
PresentationShapeCollection,
|
|
32
|
+
PresentationTable,
|
|
33
|
+
PresentationTableCollection,
|
|
34
|
+
PresentationText,
|
|
35
|
+
Slide,
|
|
36
|
+
SlideCollection,
|
|
37
|
+
type PresentationCreateOptions,
|
|
38
|
+
type PresentationElement,
|
|
39
|
+
} from "./presentation";
|
|
40
|
+
import { presentationLossState, setPresentationLossState } from "./presentation-pptx-state";
|
|
41
|
+
import {
|
|
42
|
+
CompositeArtifactState,
|
|
43
|
+
requireCompositeState,
|
|
44
|
+
type CompositeMutation,
|
|
45
|
+
type CompositeReconciliation,
|
|
46
|
+
type PreparedCompositeMutation,
|
|
47
|
+
} from "./production-composite";
|
|
48
|
+
import {
|
|
49
|
+
encodeDocumentIncrementalCommands,
|
|
50
|
+
encodeDocumentProjectionCommands,
|
|
51
|
+
encodePresentationIncrementalCommands,
|
|
52
|
+
encodePresentationProjectionCommands,
|
|
53
|
+
type DocumentProjectionTarget,
|
|
54
|
+
} from "./production-native-codecs";
|
|
55
|
+
import {
|
|
56
|
+
installSpreadsheetProjection,
|
|
57
|
+
prepareSpreadsheetMutation,
|
|
58
|
+
readSpreadsheetProperty,
|
|
59
|
+
reconcileSpreadsheetProjection,
|
|
60
|
+
} from "./production-spreadsheet-native";
|
|
61
|
+
import { ArtifactKernelRuntime, ArtifactRuntimeError } from "./runtime";
|
|
62
|
+
import {
|
|
63
|
+
Workbook as ReferenceWorkbook,
|
|
64
|
+
type SerializedWorkbook,
|
|
65
|
+
type WorkbookOptions,
|
|
66
|
+
} from "./spreadsheet";
|
|
67
|
+
import { SpreadsheetFile as ReferenceSpreadsheetFile } from "./spreadsheet-file";
|
|
68
|
+
import { LOSS_PRESERVATION } from "./spreadsheet-xlsx-state";
|
|
69
|
+
|
|
70
|
+
export {
|
|
71
|
+
SPREADSHEET_RECALCULATION_LIMITS,
|
|
72
|
+
SPREADSHEET_SNAPSHOT_LIMITS,
|
|
73
|
+
ChartSeriesCollection,
|
|
74
|
+
CommentThread,
|
|
75
|
+
ConditionalFormattingCollection,
|
|
76
|
+
DataValidationCollection,
|
|
77
|
+
FreezePanes,
|
|
78
|
+
ImageCollection,
|
|
79
|
+
Range,
|
|
80
|
+
RangeConditionalFormats,
|
|
81
|
+
RangeFormat,
|
|
82
|
+
RangeSparklines,
|
|
83
|
+
ShapeCollection,
|
|
84
|
+
SparklineGroup,
|
|
85
|
+
SparklineGroupCollection,
|
|
86
|
+
SpreadsheetChart,
|
|
87
|
+
SpreadsheetChartSeries,
|
|
88
|
+
SpreadsheetImage,
|
|
89
|
+
SpreadsheetShape,
|
|
90
|
+
Table,
|
|
91
|
+
TableCollection,
|
|
92
|
+
WorkbookComments,
|
|
93
|
+
Worksheet,
|
|
94
|
+
WorksheetCollection,
|
|
95
|
+
validateSerializedWorkbook,
|
|
96
|
+
} from "./spreadsheet";
|
|
97
|
+
export type {
|
|
98
|
+
RangeSparklineConfig,
|
|
99
|
+
RangeWritePayload,
|
|
100
|
+
SerializedWorkbook,
|
|
101
|
+
SparklineConfig,
|
|
102
|
+
SpreadsheetRecalculationLimits,
|
|
103
|
+
WorkbookChange,
|
|
104
|
+
WorkbookOptions,
|
|
105
|
+
} from "./spreadsheet";
|
|
106
|
+
export {
|
|
107
|
+
DocumentBlockCollection,
|
|
108
|
+
DocumentCommentThread,
|
|
109
|
+
DocumentComments,
|
|
110
|
+
DocumentPageBreak,
|
|
111
|
+
DocumentParagraph,
|
|
112
|
+
DocumentSection,
|
|
113
|
+
DocumentSectionStories,
|
|
114
|
+
DocumentSections,
|
|
115
|
+
DocumentStory,
|
|
116
|
+
DocumentTable,
|
|
117
|
+
DocumentTextRun,
|
|
118
|
+
TrackedChange,
|
|
119
|
+
TrackedChanges,
|
|
120
|
+
} from "./document";
|
|
121
|
+
export type {
|
|
122
|
+
DocumentBlock,
|
|
123
|
+
DocumentCreateOptions,
|
|
124
|
+
DocumentPageGeometry,
|
|
125
|
+
DocumentParagraphEdit,
|
|
126
|
+
DocumentParagraphFormat,
|
|
127
|
+
DocumentParagraphStyle,
|
|
128
|
+
DocumentRenderOptions,
|
|
129
|
+
DocumentStoryBlock,
|
|
130
|
+
DocumentTableStyle,
|
|
131
|
+
DocumentTextStyle,
|
|
132
|
+
DocumentTextStylePatch,
|
|
133
|
+
SerializedDocument,
|
|
134
|
+
SerializedDocumentBlock,
|
|
135
|
+
SerializedDocumentComment,
|
|
136
|
+
SerializedDocumentSection,
|
|
137
|
+
SerializedPageBreak,
|
|
138
|
+
SerializedParagraph,
|
|
139
|
+
SerializedStory,
|
|
140
|
+
SerializedTable,
|
|
141
|
+
SerializedTextRun,
|
|
142
|
+
SerializedTrackedChange,
|
|
143
|
+
} from "./document";
|
|
144
|
+
export {
|
|
145
|
+
InvalidPresentationInputError,
|
|
146
|
+
PresentationChart,
|
|
147
|
+
PresentationChartCollection,
|
|
148
|
+
PresentationChartSeries,
|
|
149
|
+
PresentationChartSeriesCollection,
|
|
150
|
+
PresentationGroup,
|
|
151
|
+
PresentationGroupCollection,
|
|
152
|
+
PresentationImage,
|
|
153
|
+
PresentationImageCollection,
|
|
154
|
+
PresentationLayout,
|
|
155
|
+
PresentationLayoutCollection,
|
|
156
|
+
PresentationMaster,
|
|
157
|
+
PresentationMasterCollection,
|
|
158
|
+
PresentationShape,
|
|
159
|
+
PresentationShapeCollection,
|
|
160
|
+
PresentationTable,
|
|
161
|
+
PresentationTableCell,
|
|
162
|
+
PresentationTableCollection,
|
|
163
|
+
PresentationText,
|
|
164
|
+
Slide,
|
|
165
|
+
SlideCollection,
|
|
166
|
+
SlidePlaceholderCollection,
|
|
167
|
+
UnsupportedPresentationFeatureError,
|
|
168
|
+
assertPresentationRenderPixelBudget,
|
|
169
|
+
presentationColorValue,
|
|
170
|
+
truncatePresentationText,
|
|
171
|
+
} from "./presentation";
|
|
172
|
+
export type {
|
|
173
|
+
PresentationChartConfig,
|
|
174
|
+
PresentationChartSeriesConfig,
|
|
175
|
+
PresentationChartType,
|
|
176
|
+
PresentationCreateOptions,
|
|
177
|
+
PresentationElement,
|
|
178
|
+
PresentationExportOptions,
|
|
179
|
+
PresentationFill,
|
|
180
|
+
PresentationGroupChild,
|
|
181
|
+
PresentationGroupChildConfig,
|
|
182
|
+
PresentationGroupConfig,
|
|
183
|
+
PresentationImageConfig,
|
|
184
|
+
PresentationImageResolution,
|
|
185
|
+
PresentationImageResolver,
|
|
186
|
+
PresentationInspectOptions,
|
|
187
|
+
PresentationInspectResult,
|
|
188
|
+
PresentationLayoutConfig,
|
|
189
|
+
PresentationLine,
|
|
190
|
+
PresentationMasterConfig,
|
|
191
|
+
PresentationPosition,
|
|
192
|
+
PresentationRasterImageContentType,
|
|
193
|
+
PresentationResolvedObject,
|
|
194
|
+
PresentationShapeConfig,
|
|
195
|
+
PresentationShapeGeometry,
|
|
196
|
+
PresentationTableCellConfig,
|
|
197
|
+
PresentationTableCellInput,
|
|
198
|
+
PresentationTableConfig,
|
|
199
|
+
PresentationTemplateElement,
|
|
200
|
+
PresentationTextStyle,
|
|
201
|
+
} from "./presentation";
|
|
202
|
+
export { SpreadsheetFidelityError, SpreadsheetSecurityError } from "./spreadsheet-file";
|
|
203
|
+
export type {
|
|
204
|
+
SpreadsheetFidelityIssue,
|
|
205
|
+
SpreadsheetLossPreservationEnvelope,
|
|
206
|
+
SpreadsheetXlsxExportOptions,
|
|
207
|
+
SpreadsheetXlsxImportLimits,
|
|
208
|
+
SpreadsheetXlsxImportOptions,
|
|
209
|
+
} from "./spreadsheet-file";
|
|
210
|
+
|
|
211
|
+
export type ArtifactBatchControls<Root> = Readonly<{
|
|
212
|
+
/** One atomic host/native transaction; nested edits reconcile exactly once. */
|
|
213
|
+
batch<Result>(callback: (artifact: Root) => Result): Result;
|
|
214
|
+
/** Idempotently releases the owned exact native session. */
|
|
215
|
+
dispose(): void;
|
|
216
|
+
}>;
|
|
217
|
+
|
|
218
|
+
export type Workbook = ReferenceWorkbook & ArtifactBatchControls<ReferenceWorkbook>;
|
|
219
|
+
export type Document = ReferenceDocument & ArtifactBatchControls<ReferenceDocument>;
|
|
220
|
+
export type Presentation = ReferencePresentation & ArtifactBatchControls<ReferencePresentation>;
|
|
221
|
+
|
|
222
|
+
export type WorkbookFactory = Readonly<{
|
|
223
|
+
prototype: ReferenceWorkbook;
|
|
224
|
+
[Symbol.hasInstance](value: unknown): boolean;
|
|
225
|
+
create(options?: WorkbookOptions): Workbook;
|
|
226
|
+
fromCSV(csvText: string, options?: { sheetName?: string; delimiter?: string }): Promise<Workbook>;
|
|
227
|
+
fromJSON(input: unknown): Workbook;
|
|
228
|
+
}>;
|
|
229
|
+
|
|
230
|
+
export type DocumentFactory = Readonly<{
|
|
231
|
+
prototype: ReferenceDocument;
|
|
232
|
+
[Symbol.hasInstance](value: unknown): boolean;
|
|
233
|
+
create(options?: DocumentCreateOptions): Document;
|
|
234
|
+
fromJSON(input: unknown): Document;
|
|
235
|
+
}>;
|
|
236
|
+
|
|
237
|
+
export type PresentationFactory = Readonly<{
|
|
238
|
+
prototype: ReferencePresentation;
|
|
239
|
+
[Symbol.hasInstance](value: unknown): boolean;
|
|
240
|
+
create(options?: PresentationCreateOptions): Presentation;
|
|
241
|
+
}>;
|
|
242
|
+
|
|
243
|
+
let configuredRuntime: ArtifactKernelRuntime | null = null;
|
|
244
|
+
|
|
245
|
+
/**
|
|
246
|
+
* Installs the one exact native runtime selected by host bootstrap. Runtime
|
|
247
|
+
* replacement is deliberately forbidden: a process that needs another target
|
|
248
|
+
* must use an isolated worker/process and configure it once.
|
|
249
|
+
*/
|
|
250
|
+
export function configureArtifactRuntime(runtime: ArtifactKernelRuntime): void {
|
|
251
|
+
if (runtime.kind !== "native" || runtime.target === "wasm-web") {
|
|
252
|
+
throw new ArtifactRuntimeError(
|
|
253
|
+
"ARTIFACT_RUNTIME_UNAVAILABLE",
|
|
254
|
+
"The synchronous artifact facade requires an exact native N-API runtime",
|
|
255
|
+
);
|
|
256
|
+
}
|
|
257
|
+
if (configuredRuntime && configuredRuntime !== runtime) {
|
|
258
|
+
throw new ArtifactRuntimeError(
|
|
259
|
+
"ARTIFACT_RUNTIME_INCOMPATIBLE",
|
|
260
|
+
"A different artifact runtime is already configured in this process",
|
|
261
|
+
);
|
|
262
|
+
}
|
|
263
|
+
configuredRuntime = runtime;
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
/** Exact configured runtime, or null before the host bootstrap runs. */
|
|
267
|
+
export function getConfiguredArtifactRuntime(): ArtifactKernelRuntime | null {
|
|
268
|
+
return configuredRuntime;
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
const WorkbookFacade = createStaticFacade(ReferenceWorkbook, "Workbook", {
|
|
272
|
+
create(options: WorkbookOptions = {}): Workbook {
|
|
273
|
+
return attachWorkbook(ReferenceWorkbook.create(options), randomNamespace());
|
|
274
|
+
},
|
|
275
|
+
async fromCSV(
|
|
276
|
+
csvText: string,
|
|
277
|
+
options: { sheetName?: string; delimiter?: string } = {},
|
|
278
|
+
): Promise<Workbook> {
|
|
279
|
+
return attachWorkbook(await ReferenceWorkbook.fromCSV(csvText, options), randomNamespace());
|
|
280
|
+
},
|
|
281
|
+
fromJSON(input: unknown): Workbook {
|
|
282
|
+
return attachWorkbook(ReferenceWorkbook.fromJSON(input), randomNamespace());
|
|
283
|
+
},
|
|
284
|
+
});
|
|
285
|
+
|
|
286
|
+
const DocumentFacade = createStaticFacade(ReferenceDocument, "Document", {
|
|
287
|
+
create(options: DocumentCreateOptions = {}): Document {
|
|
288
|
+
const document = ReferenceDocument.create(options);
|
|
289
|
+
return attachDocument(document, BigInt(`0x${document.idNamespace}`));
|
|
290
|
+
},
|
|
291
|
+
fromJSON(input: unknown): Document {
|
|
292
|
+
const document = ReferenceDocument.fromJSON(input);
|
|
293
|
+
return attachDocument(document, BigInt(`0x${document.idNamespace}`));
|
|
294
|
+
},
|
|
295
|
+
});
|
|
296
|
+
|
|
297
|
+
const PresentationFacade = createStaticFacade(ReferencePresentation, "Presentation", {
|
|
298
|
+
create(options: PresentationCreateOptions = {}): Presentation {
|
|
299
|
+
return attachPresentation(ReferencePresentation.create(options), randomNamespace());
|
|
300
|
+
},
|
|
301
|
+
});
|
|
302
|
+
|
|
303
|
+
/** Skill-compatible factory; returned objects are exact native composites. */
|
|
304
|
+
export const Workbook = WorkbookFacade as unknown as WorkbookFactory;
|
|
305
|
+
/** Skill-compatible factory; returned objects are exact native composites. */
|
|
306
|
+
export const Document = DocumentFacade as unknown as DocumentFactory;
|
|
307
|
+
/** Skill-compatible factory; returned objects are exact native composites. */
|
|
308
|
+
export const Presentation = PresentationFacade as unknown as PresentationFactory;
|
|
309
|
+
|
|
310
|
+
// eslint-disable-next-line typescript/no-extraneous-class -- stable skill facade.
|
|
311
|
+
export class SpreadsheetFile {
|
|
312
|
+
static async importXlsx(
|
|
313
|
+
...args: Parameters<typeof ReferenceSpreadsheetFile.importXlsx>
|
|
314
|
+
): Promise<Workbook> {
|
|
315
|
+
requireConfiguredRuntime();
|
|
316
|
+
const workbook = await ReferenceSpreadsheetFile.importXlsx(...args);
|
|
317
|
+
return attachWorkbook(workbook, randomNamespace());
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
static async exportXlsx(
|
|
321
|
+
workbook: ReferenceWorkbook,
|
|
322
|
+
options: Parameters<typeof ReferenceSpreadsheetFile.exportXlsx>[1] = {},
|
|
323
|
+
): Promise<FileBlob> {
|
|
324
|
+
const raw = rawArtifact<ReferenceWorkbook>(workbook, "spreadsheet");
|
|
325
|
+
return await ReferenceSpreadsheetFile.exportXlsx(raw, options);
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
static fidelityReport(
|
|
329
|
+
workbook: ReferenceWorkbook,
|
|
330
|
+
): ReturnType<typeof ReferenceSpreadsheetFile.fidelityReport> {
|
|
331
|
+
return ReferenceSpreadsheetFile.fidelityReport(rawArtifact(workbook, "spreadsheet"));
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
static lossPreservationEnvelope(
|
|
335
|
+
workbook: ReferenceWorkbook,
|
|
336
|
+
): ReturnType<typeof ReferenceSpreadsheetFile.lossPreservationEnvelope> {
|
|
337
|
+
return ReferenceSpreadsheetFile.lossPreservationEnvelope(rawArtifact(workbook, "spreadsheet"));
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
static async attachLossPreservationEnvelope(
|
|
341
|
+
workbook: ReferenceWorkbook,
|
|
342
|
+
envelope: Parameters<typeof ReferenceSpreadsheetFile.attachLossPreservationEnvelope>[1],
|
|
343
|
+
options: Parameters<typeof ReferenceSpreadsheetFile.attachLossPreservationEnvelope>[2] = {},
|
|
344
|
+
): Promise<void> {
|
|
345
|
+
const state = requireCompositeState(workbook, "spreadsheet");
|
|
346
|
+
await state.mutate(
|
|
347
|
+
() =>
|
|
348
|
+
ReferenceSpreadsheetFile.attachLossPreservationEnvelope(
|
|
349
|
+
state.rawRoot() as ReferenceWorkbook,
|
|
350
|
+
envelope,
|
|
351
|
+
options,
|
|
352
|
+
),
|
|
353
|
+
{ member: "attachLossPreservationEnvelope", owner: state.rawRoot() },
|
|
354
|
+
);
|
|
355
|
+
}
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
// eslint-disable-next-line typescript/no-extraneous-class -- stable skill facade.
|
|
359
|
+
export class DocumentFile {
|
|
360
|
+
static async importDocx(
|
|
361
|
+
...args: Parameters<typeof ReferenceDocumentFile.importDocx>
|
|
362
|
+
): Promise<Document> {
|
|
363
|
+
requireConfiguredRuntime();
|
|
364
|
+
const document = await ReferenceDocumentFile.importDocx(...args);
|
|
365
|
+
return attachDocument(document, BigInt(`0x${document.idNamespace}`));
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
static async exportDocx(document: ReferenceDocument): Promise<FileBlob> {
|
|
369
|
+
return await ReferenceDocumentFile.exportDocx(rawArtifact(document, "document"));
|
|
370
|
+
}
|
|
371
|
+
}
|
|
372
|
+
|
|
373
|
+
// eslint-disable-next-line typescript/no-extraneous-class -- stable skill facade.
|
|
374
|
+
export class PresentationFile {
|
|
375
|
+
static async importPptx(
|
|
376
|
+
...args: Parameters<typeof ReferencePresentationFile.importPptx>
|
|
377
|
+
): Promise<Presentation> {
|
|
378
|
+
requireConfiguredRuntime();
|
|
379
|
+
const presentation = await ReferencePresentationFile.importPptx(...args);
|
|
380
|
+
return attachPresentation(presentation, randomNamespace());
|
|
381
|
+
}
|
|
382
|
+
|
|
383
|
+
static async exportPptx(
|
|
384
|
+
presentation: ReferencePresentation,
|
|
385
|
+
options: Parameters<typeof ReferencePresentationFile.exportPptx>[1] = {},
|
|
386
|
+
): Promise<FileBlob> {
|
|
387
|
+
return await ReferencePresentationFile.exportPptx(
|
|
388
|
+
rawArtifact(presentation, "presentation"),
|
|
389
|
+
options,
|
|
390
|
+
);
|
|
391
|
+
}
|
|
392
|
+
|
|
393
|
+
static fidelityReport(
|
|
394
|
+
presentation: ReferencePresentation,
|
|
395
|
+
): ReturnType<typeof ReferencePresentationFile.fidelityReport> {
|
|
396
|
+
return ReferencePresentationFile.fidelityReport(rawArtifact(presentation, "presentation"));
|
|
397
|
+
}
|
|
398
|
+
|
|
399
|
+
static lossPreservationEnvelope(
|
|
400
|
+
presentation: ReferencePresentation,
|
|
401
|
+
): ReturnType<typeof ReferencePresentationFile.lossPreservationEnvelope> {
|
|
402
|
+
return ReferencePresentationFile.lossPreservationEnvelope(
|
|
403
|
+
rawArtifact(presentation, "presentation"),
|
|
404
|
+
);
|
|
405
|
+
}
|
|
406
|
+
}
|
|
407
|
+
|
|
408
|
+
export type ArtifactCompositeDiagnostics = Readonly<{
|
|
409
|
+
version: 1;
|
|
410
|
+
modality: "spreadsheet" | "document" | "presentation";
|
|
411
|
+
namespace: string;
|
|
412
|
+
runtimeTarget: string;
|
|
413
|
+
runtimeBuildIdentity: string;
|
|
414
|
+
nativeRevision: bigint;
|
|
415
|
+
nativeStateHash: string;
|
|
416
|
+
nativeSnapshot: Uint8Array;
|
|
417
|
+
hostProjection: SerializedWorkbook | SerializedDocument | Record<string, unknown>;
|
|
418
|
+
}>;
|
|
419
|
+
|
|
420
|
+
/**
|
|
421
|
+
* Point-in-time diagnostics only. This is deliberately not a persistence,
|
|
422
|
+
* restore, or provenance envelope: presentation layout snapshots omit media
|
|
423
|
+
* bytes and host capabilities, and the two projections are not cryptographically
|
|
424
|
+
* bound. Durable state uses canonical collaboration snapshots plus the owned
|
|
425
|
+
* format-loss envelope instead of pretending this view is restorable.
|
|
426
|
+
*/
|
|
427
|
+
export function getArtifactCompositeDiagnostics(
|
|
428
|
+
artifact: ReferenceWorkbook | ReferenceDocument | ReferencePresentation,
|
|
429
|
+
): ArtifactCompositeDiagnostics {
|
|
430
|
+
const state = requireCompositeState(artifact);
|
|
431
|
+
const root = state.rawRoot() as ReferenceWorkbook | ReferenceDocument | ReferencePresentation;
|
|
432
|
+
const hostProjection =
|
|
433
|
+
state.modality === "presentation"
|
|
434
|
+
? (root as ReferencePresentation).layoutSnapshot()
|
|
435
|
+
: (root as ReferenceWorkbook | ReferenceDocument).toJSON();
|
|
436
|
+
return Object.freeze({
|
|
437
|
+
version: 1,
|
|
438
|
+
modality: state.modality,
|
|
439
|
+
namespace: u64Hex(state.namespace),
|
|
440
|
+
runtimeTarget: state.native.target,
|
|
441
|
+
runtimeBuildIdentity: state.native.buildIdentity,
|
|
442
|
+
nativeRevision: state.native.revision(),
|
|
443
|
+
nativeStateHash: state.native.stateHash(),
|
|
444
|
+
nativeSnapshot: state.native.snapshot().slice(),
|
|
445
|
+
hostProjection: structuredClone(hostProjection),
|
|
446
|
+
});
|
|
447
|
+
}
|
|
448
|
+
|
|
449
|
+
/** Idempotently closes the exact native session owned by a facade artifact. */
|
|
450
|
+
export function disposeArtifact(
|
|
451
|
+
artifact: ReferenceWorkbook | ReferenceDocument | ReferencePresentation,
|
|
452
|
+
): void {
|
|
453
|
+
requireCompositeState(artifact).dispose();
|
|
454
|
+
}
|
|
455
|
+
|
|
456
|
+
function attachWorkbook(workbook: ReferenceWorkbook, namespace: bigint): Workbook {
|
|
457
|
+
const runtime = requireConfiguredRuntime();
|
|
458
|
+
const reconcile = (root: ReferenceWorkbook) =>
|
|
459
|
+
reconcileSpreadsheetProjection(root, runtime, namespace);
|
|
460
|
+
const reconciliation = reconcile(workbook);
|
|
461
|
+
const state = new CompositeArtifactState({
|
|
462
|
+
modality: "spreadsheet",
|
|
463
|
+
namespace,
|
|
464
|
+
root: workbook,
|
|
465
|
+
reconciliation,
|
|
466
|
+
reconcile,
|
|
467
|
+
prepareMutation: prepareSpreadsheetMutation,
|
|
468
|
+
installProjection: installSpreadsheetProjection,
|
|
469
|
+
readProperty: readSpreadsheetProperty,
|
|
470
|
+
captureAuxiliary: captureSpreadsheetAuxiliary,
|
|
471
|
+
restoreAuxiliary: restoreSpreadsheetAuxiliary,
|
|
472
|
+
});
|
|
473
|
+
return state.proxy() as Workbook;
|
|
474
|
+
}
|
|
475
|
+
|
|
476
|
+
function attachDocument(document: ReferenceDocument, namespace: bigint): Document {
|
|
477
|
+
const runtime = requireConfiguredRuntime();
|
|
478
|
+
const reconcile = (root: ReferenceDocument) =>
|
|
479
|
+
reconcileDocumentProjection(root, runtime, namespace);
|
|
480
|
+
const reconciliation = reconcile(document);
|
|
481
|
+
const state = new CompositeArtifactState({
|
|
482
|
+
modality: "document",
|
|
483
|
+
namespace,
|
|
484
|
+
root: document,
|
|
485
|
+
reconciliation,
|
|
486
|
+
reconcile,
|
|
487
|
+
prepareMutation: prepareDocumentMutation,
|
|
488
|
+
captureAuxiliary: captureDocumentAuxiliary,
|
|
489
|
+
restoreAuxiliary: restoreDocumentAuxiliary,
|
|
490
|
+
});
|
|
491
|
+
return state.proxy() as Document;
|
|
492
|
+
}
|
|
493
|
+
|
|
494
|
+
function attachPresentation(presentation: ReferencePresentation, namespace: bigint): Presentation {
|
|
495
|
+
const runtime = requireConfiguredRuntime();
|
|
496
|
+
const reconcile = (root: ReferencePresentation) =>
|
|
497
|
+
reconcilePresentationProjection(root, runtime, namespace);
|
|
498
|
+
const reconciliation = reconcile(presentation);
|
|
499
|
+
const state = new CompositeArtifactState({
|
|
500
|
+
modality: "presentation",
|
|
501
|
+
namespace,
|
|
502
|
+
root: presentation,
|
|
503
|
+
reconciliation,
|
|
504
|
+
reconcile,
|
|
505
|
+
prepareMutation: preparePresentationMutation,
|
|
506
|
+
captureAuxiliary: capturePresentationAuxiliary,
|
|
507
|
+
restoreAuxiliary: restorePresentationAuxiliary,
|
|
508
|
+
});
|
|
509
|
+
return state.proxy() as Presentation;
|
|
510
|
+
}
|
|
511
|
+
|
|
512
|
+
function reconcileDocumentProjection(
|
|
513
|
+
document: ReferenceDocument,
|
|
514
|
+
runtime: ArtifactKernelRuntime,
|
|
515
|
+
namespace: bigint,
|
|
516
|
+
): CompositeReconciliation {
|
|
517
|
+
const session = NativeDocumentSession.create(runtime, namespace);
|
|
518
|
+
try {
|
|
519
|
+
const commands = encodeDocumentProjectionCommands(document.toJSON());
|
|
520
|
+
if (envelopeCommandCount(commands) > 0) session.applyCommands(commands);
|
|
521
|
+
return { session };
|
|
522
|
+
} catch (cause) {
|
|
523
|
+
session.dispose();
|
|
524
|
+
throw cause;
|
|
525
|
+
}
|
|
526
|
+
}
|
|
527
|
+
|
|
528
|
+
function prepareDocumentMutation(
|
|
529
|
+
mutation: CompositeMutation,
|
|
530
|
+
state: CompositeArtifactState<ReferenceDocument>,
|
|
531
|
+
): PreparedCompositeMutation | null {
|
|
532
|
+
const root = state.rawRoot();
|
|
533
|
+
const owner = mutation.owner;
|
|
534
|
+
const member = mutation.member;
|
|
535
|
+
|
|
536
|
+
if (owner instanceof DocumentBlockCollection || owner instanceof DocumentStory) {
|
|
537
|
+
if (
|
|
538
|
+
member === "addParagraph" ||
|
|
539
|
+
member === "addHeading" ||
|
|
540
|
+
member === "addTable" ||
|
|
541
|
+
member === "addPageBreak"
|
|
542
|
+
) {
|
|
543
|
+
const target =
|
|
544
|
+
owner instanceof DocumentStory
|
|
545
|
+
? documentStoryTarget(root, owner)
|
|
546
|
+
: { kind: "body" as const };
|
|
547
|
+
return commitDocumentMutation(state, (result) => {
|
|
548
|
+
if (!isSerializedDocumentBlock(result)) {
|
|
549
|
+
throw new Error(`${String(member)} did not return a document block`);
|
|
550
|
+
}
|
|
551
|
+
return [{ kind: "block.add", target, block: result.serialize() }];
|
|
552
|
+
});
|
|
553
|
+
}
|
|
554
|
+
}
|
|
555
|
+
|
|
556
|
+
if (owner instanceof DocumentParagraph) {
|
|
557
|
+
if (member === "setStyle") {
|
|
558
|
+
const style = mutation.arguments?.[0] as Parameters<DocumentParagraph["setStyle"]>[0];
|
|
559
|
+
return commitDocumentMutation(state, () => [
|
|
560
|
+
{ kind: "paragraph.style", id: owner.id, style },
|
|
561
|
+
]);
|
|
562
|
+
}
|
|
563
|
+
if (member === "format") {
|
|
564
|
+
const format = mutation.arguments?.[0] as Parameters<DocumentParagraph["format"]>[0];
|
|
565
|
+
return commitDocumentMutation(state, () => [
|
|
566
|
+
{ kind: "paragraph.format", id: owner.id, format },
|
|
567
|
+
]);
|
|
568
|
+
}
|
|
569
|
+
if (member === "edit") {
|
|
570
|
+
const edit = documentParagraphEdit(mutation.arguments ?? []);
|
|
571
|
+
if (!edit) return null;
|
|
572
|
+
return commitDocumentMutation(state, () => [
|
|
573
|
+
{ kind: "paragraph.edit", id: owner.id, ...edit },
|
|
574
|
+
]);
|
|
575
|
+
}
|
|
576
|
+
if (member === "append") {
|
|
577
|
+
const text = mutation.arguments?.[0];
|
|
578
|
+
const style = mutation.arguments?.[1] ?? {};
|
|
579
|
+
if (typeof text !== "string" || typeof style !== "object" || style === null) return null;
|
|
580
|
+
const start = owner.text.length;
|
|
581
|
+
return commitDocumentMutation(state, () => [
|
|
582
|
+
{
|
|
583
|
+
kind: "paragraph.edit",
|
|
584
|
+
id: owner.id,
|
|
585
|
+
start,
|
|
586
|
+
end: start,
|
|
587
|
+
text,
|
|
588
|
+
style: style as DocumentTextStyle,
|
|
589
|
+
},
|
|
590
|
+
]);
|
|
591
|
+
}
|
|
592
|
+
if (member === "text") {
|
|
593
|
+
const before = owner.text;
|
|
594
|
+
return commitDocumentMutation(state, () => {
|
|
595
|
+
const edit = minimalDocumentTextEdit(before, owner.text);
|
|
596
|
+
return edit ? [{ kind: "paragraph.edit", id: owner.id, ...edit }] : [];
|
|
597
|
+
});
|
|
598
|
+
}
|
|
599
|
+
if (member === "replace") {
|
|
600
|
+
const search = mutation.arguments?.[0];
|
|
601
|
+
const before = owner.text;
|
|
602
|
+
if (
|
|
603
|
+
typeof search !== "string" ||
|
|
604
|
+
search.length === 0 ||
|
|
605
|
+
before.indexOf(search) !== before.lastIndexOf(search)
|
|
606
|
+
) {
|
|
607
|
+
return null;
|
|
608
|
+
}
|
|
609
|
+
return commitDocumentMutation(state, () => {
|
|
610
|
+
const edit = minimalDocumentTextEdit(before, owner.text);
|
|
611
|
+
return edit ? [{ kind: "paragraph.edit", id: owner.id, ...edit }] : [];
|
|
612
|
+
});
|
|
613
|
+
}
|
|
614
|
+
}
|
|
615
|
+
|
|
616
|
+
if (owner instanceof DocumentTable && member === "setStyle") {
|
|
617
|
+
const style = mutation.arguments?.[0] as Parameters<DocumentTable["setStyle"]>[0];
|
|
618
|
+
return commitDocumentMutation(state, () => [{ kind: "table.style", id: owner.id, style }]);
|
|
619
|
+
}
|
|
620
|
+
if (owner === root && (member === "setEvenAndOddHeaders" || member === "setTrackRevisions")) {
|
|
621
|
+
const enabled = mutation.arguments?.[0];
|
|
622
|
+
if (typeof enabled !== "boolean") return null;
|
|
623
|
+
return commitDocumentMutation(state, () => [
|
|
624
|
+
{
|
|
625
|
+
kind: "document.flags",
|
|
626
|
+
...(member === "setEvenAndOddHeaders"
|
|
627
|
+
? { evenAndOddHeaders: enabled }
|
|
628
|
+
: { trackRevisions: enabled }),
|
|
629
|
+
},
|
|
630
|
+
]);
|
|
631
|
+
}
|
|
632
|
+
if (owner instanceof DocumentSections && member === "add") {
|
|
633
|
+
return commitDocumentMutation(state, (result) => {
|
|
634
|
+
if (!(result instanceof DocumentSection))
|
|
635
|
+
throw new Error("Section add did not return a section");
|
|
636
|
+
return [{ kind: "section.add", section: result.serialize() }];
|
|
637
|
+
});
|
|
638
|
+
}
|
|
639
|
+
if (owner instanceof DocumentSection && member === "setTitlePage") {
|
|
640
|
+
const enabled = mutation.arguments?.[0];
|
|
641
|
+
if (typeof enabled !== "boolean") return null;
|
|
642
|
+
return commitDocumentMutation(state, () => [
|
|
643
|
+
{ kind: "section.title", id: owner.id, titlePage: enabled },
|
|
644
|
+
]);
|
|
645
|
+
}
|
|
646
|
+
if (owner instanceof DocumentComments) {
|
|
647
|
+
if (member === "setSelf") return { commit: () => false };
|
|
648
|
+
if (member === "addThread") {
|
|
649
|
+
return commitDocumentMutation(state, (result) => {
|
|
650
|
+
if (!(result instanceof DocumentCommentThread))
|
|
651
|
+
throw new Error("Comment add did not return a thread");
|
|
652
|
+
return [{ kind: "comment.add", comment: result.serialize() }];
|
|
653
|
+
});
|
|
654
|
+
}
|
|
655
|
+
}
|
|
656
|
+
if (owner instanceof DocumentCommentThread) {
|
|
657
|
+
if (member === "addReply") {
|
|
658
|
+
const before = owner.replies.length;
|
|
659
|
+
return commitDocumentMutation(state, () => {
|
|
660
|
+
const reply = owner.serialize().replies[before];
|
|
661
|
+
return reply ? [{ kind: "comment.reply", id: owner.id, reply }] : [];
|
|
662
|
+
});
|
|
663
|
+
}
|
|
664
|
+
if (member === "resolve" || member === "reopen") {
|
|
665
|
+
const before = owner.resolved;
|
|
666
|
+
return commitDocumentMutation(state, () =>
|
|
667
|
+
before === owner.resolved
|
|
668
|
+
? []
|
|
669
|
+
: [{ kind: "comment.resolved", id: owner.id, resolved: owner.resolved }],
|
|
670
|
+
);
|
|
671
|
+
}
|
|
672
|
+
}
|
|
673
|
+
if (owner instanceof TrackedChanges && member === "add") {
|
|
674
|
+
return commitDocumentMutation(state, (result) => {
|
|
675
|
+
if (
|
|
676
|
+
!result ||
|
|
677
|
+
typeof result !== "object" ||
|
|
678
|
+
typeof Reflect.get(result, "serialize") !== "function"
|
|
679
|
+
) {
|
|
680
|
+
throw new Error("Tracked-change add did not return a change");
|
|
681
|
+
}
|
|
682
|
+
return [
|
|
683
|
+
{
|
|
684
|
+
kind: "tracked.add",
|
|
685
|
+
change: (
|
|
686
|
+
Reflect.get(result, "serialize") as () => ReturnType<
|
|
687
|
+
ReferenceDocument["toJSON"]
|
|
688
|
+
>["changes"][number]
|
|
689
|
+
).call(result),
|
|
690
|
+
},
|
|
691
|
+
];
|
|
692
|
+
});
|
|
693
|
+
}
|
|
694
|
+
return null;
|
|
695
|
+
}
|
|
696
|
+
|
|
697
|
+
function commitDocumentMutation(
|
|
698
|
+
state: CompositeArtifactState<ReferenceDocument>,
|
|
699
|
+
commands: (result: unknown) => Parameters<typeof encodeDocumentIncrementalCommands>[0],
|
|
700
|
+
): PreparedCompositeMutation {
|
|
701
|
+
return {
|
|
702
|
+
commit(result) {
|
|
703
|
+
const batch = commands(result);
|
|
704
|
+
if (batch.length === 0) return false;
|
|
705
|
+
const session = state.native;
|
|
706
|
+
if (!(session instanceof NativeDocumentSession))
|
|
707
|
+
throw new TypeError("Expected native document session");
|
|
708
|
+
const before = session.revision();
|
|
709
|
+
session.applyCommands(encodeDocumentIncrementalCommands(batch));
|
|
710
|
+
return session.revision() > before;
|
|
711
|
+
},
|
|
712
|
+
};
|
|
713
|
+
}
|
|
714
|
+
|
|
715
|
+
function documentStoryTarget(
|
|
716
|
+
document: ReferenceDocument,
|
|
717
|
+
story: DocumentStory,
|
|
718
|
+
): DocumentProjectionTarget {
|
|
719
|
+
for (const section of document.sections.items) {
|
|
720
|
+
for (const storyKind of ["header", "footer"] as const) {
|
|
721
|
+
const collection = storyKind === "header" ? section.headers : section.footers;
|
|
722
|
+
for (const variant of ["default", "first", "even"] as const) {
|
|
723
|
+
if (collection[variant] === story)
|
|
724
|
+
return { kind: "story", sectionId: section.id, storyKind, variant };
|
|
725
|
+
}
|
|
726
|
+
}
|
|
727
|
+
}
|
|
728
|
+
throw new Error(`Document story is not attached: ${story.id}`);
|
|
729
|
+
}
|
|
730
|
+
|
|
731
|
+
function isSerializedDocumentBlock(value: unknown): value is {
|
|
732
|
+
serialize(): SerializedDocumentBlock;
|
|
733
|
+
} {
|
|
734
|
+
return (
|
|
735
|
+
typeof value === "object" &&
|
|
736
|
+
value !== null &&
|
|
737
|
+
typeof Reflect.get(value, "serialize") === "function"
|
|
738
|
+
);
|
|
739
|
+
}
|
|
740
|
+
|
|
741
|
+
function documentParagraphEdit(
|
|
742
|
+
args: readonly unknown[],
|
|
743
|
+
): { start: number; end: number; text: string; style?: DocumentTextStyle } | null {
|
|
744
|
+
if (typeof args[0] === "number") {
|
|
745
|
+
if (typeof args[1] !== "number" || typeof args[2] !== "string") return null;
|
|
746
|
+
return {
|
|
747
|
+
start: args[0],
|
|
748
|
+
end: args[1],
|
|
749
|
+
text: args[2],
|
|
750
|
+
...(args[3] && typeof args[3] === "object" ? { style: args[3] as DocumentTextStyle } : {}),
|
|
751
|
+
};
|
|
752
|
+
}
|
|
753
|
+
const edit = args[0] as
|
|
754
|
+
| { start?: unknown; end?: unknown; text?: unknown; style?: unknown }
|
|
755
|
+
| undefined;
|
|
756
|
+
if (
|
|
757
|
+
!edit ||
|
|
758
|
+
typeof edit.start !== "number" ||
|
|
759
|
+
typeof edit.end !== "number" ||
|
|
760
|
+
typeof edit.text !== "string"
|
|
761
|
+
) {
|
|
762
|
+
return null;
|
|
763
|
+
}
|
|
764
|
+
return {
|
|
765
|
+
start: edit.start,
|
|
766
|
+
end: edit.end,
|
|
767
|
+
text: edit.text,
|
|
768
|
+
...(edit.style && typeof edit.style === "object"
|
|
769
|
+
? { style: edit.style as DocumentTextStyle }
|
|
770
|
+
: {}),
|
|
771
|
+
};
|
|
772
|
+
}
|
|
773
|
+
|
|
774
|
+
function minimalDocumentTextEdit(
|
|
775
|
+
before: string,
|
|
776
|
+
after: string,
|
|
777
|
+
): { start: number; end: number; text: string } | null {
|
|
778
|
+
if (before === after) return null;
|
|
779
|
+
let start = 0;
|
|
780
|
+
while (start < before.length && start < after.length && before[start] === after[start])
|
|
781
|
+
start += 1;
|
|
782
|
+
let beforeEnd = before.length;
|
|
783
|
+
let afterEnd = after.length;
|
|
784
|
+
while (beforeEnd > start && afterEnd > start && before[beforeEnd - 1] === after[afterEnd - 1]) {
|
|
785
|
+
beforeEnd -= 1;
|
|
786
|
+
afterEnd -= 1;
|
|
787
|
+
}
|
|
788
|
+
return { start, end: beforeEnd, text: after.slice(start, afterEnd) };
|
|
789
|
+
}
|
|
790
|
+
|
|
791
|
+
function reconcilePresentationProjection(
|
|
792
|
+
presentation: ReferencePresentation,
|
|
793
|
+
runtime: ArtifactKernelRuntime,
|
|
794
|
+
namespace: bigint,
|
|
795
|
+
): CompositeReconciliation {
|
|
796
|
+
const session = NativePresentationSession.create(runtime, namespace);
|
|
797
|
+
try {
|
|
798
|
+
const commands = encodePresentationProjectionCommands(presentation, namespace);
|
|
799
|
+
if (envelopeCommandCount(commands) > 0) session.applyCommands(commands);
|
|
800
|
+
return { session };
|
|
801
|
+
} catch (cause) {
|
|
802
|
+
session.dispose();
|
|
803
|
+
throw cause;
|
|
804
|
+
}
|
|
805
|
+
}
|
|
806
|
+
|
|
807
|
+
function preparePresentationMutation(
|
|
808
|
+
mutation: CompositeMutation,
|
|
809
|
+
state: CompositeArtifactState<ReferencePresentation>,
|
|
810
|
+
): PreparedCompositeMutation | null {
|
|
811
|
+
const root = state.rawRoot();
|
|
812
|
+
const owner = mutation.owner;
|
|
813
|
+
const member = mutation.member;
|
|
814
|
+
|
|
815
|
+
if (owner instanceof SlideCollection && member === "add") {
|
|
816
|
+
const index = root.slides.items.length;
|
|
817
|
+
return commitPresentationMutation(state, (result) => {
|
|
818
|
+
if (!(result instanceof Slide)) throw new Error("Slide add did not return a slide");
|
|
819
|
+
return [{ kind: "slide.create", slide: result, index }];
|
|
820
|
+
});
|
|
821
|
+
}
|
|
822
|
+
|
|
823
|
+
if (
|
|
824
|
+
(owner instanceof PresentationShapeCollection ||
|
|
825
|
+
owner instanceof PresentationChartCollection ||
|
|
826
|
+
owner instanceof PresentationImageCollection ||
|
|
827
|
+
owner instanceof PresentationTableCollection ||
|
|
828
|
+
owner instanceof PresentationGroupCollection) &&
|
|
829
|
+
member === "add"
|
|
830
|
+
) {
|
|
831
|
+
return commitPresentationMutation(state, (result) => {
|
|
832
|
+
if (!isPresentationElement(result))
|
|
833
|
+
throw new Error("Presentation add did not return an element");
|
|
834
|
+
const index = result.slide.elements.indexOf(result);
|
|
835
|
+
if (index < 0) throw new Error("Presentation element was not attached to its slide");
|
|
836
|
+
return [{ kind: "node.insert", slideId: result.slide.id, index, element: result }];
|
|
837
|
+
});
|
|
838
|
+
}
|
|
839
|
+
|
|
840
|
+
if (owner instanceof Slide) {
|
|
841
|
+
if (member === "title") {
|
|
842
|
+
return commitPresentationMutation(state, () => [
|
|
843
|
+
{ kind: "slide.title", id: owner.id, title: owner.title },
|
|
844
|
+
]);
|
|
845
|
+
}
|
|
846
|
+
if (member === "setLayout") {
|
|
847
|
+
return commitPresentationMutation(state, () => [
|
|
848
|
+
{
|
|
849
|
+
kind: "slide.layout",
|
|
850
|
+
id: owner.id,
|
|
851
|
+
...(owner.layout ? { layoutId: owner.layout.id } : {}),
|
|
852
|
+
},
|
|
853
|
+
]);
|
|
854
|
+
}
|
|
855
|
+
}
|
|
856
|
+
|
|
857
|
+
if (owner === root.slideSize && (member === "width" || member === "height")) {
|
|
858
|
+
return commitPresentationMutation(state, () => [
|
|
859
|
+
{
|
|
860
|
+
kind: "presentation.size",
|
|
861
|
+
width: root.slideSize.width,
|
|
862
|
+
height: root.slideSize.height,
|
|
863
|
+
},
|
|
864
|
+
]);
|
|
865
|
+
}
|
|
866
|
+
|
|
867
|
+
if (owner instanceof PresentationText) {
|
|
868
|
+
const target = findPresentationTextOwner(root, owner);
|
|
869
|
+
if (!target) return null;
|
|
870
|
+
return commitPresentationMutation(state, () =>
|
|
871
|
+
target.kind === "notes"
|
|
872
|
+
? [{ kind: "slide.notes", id: target.slide.id, notes: owner }]
|
|
873
|
+
: [{ kind: "node.update", element: target.element }],
|
|
874
|
+
);
|
|
875
|
+
}
|
|
876
|
+
|
|
877
|
+
if (isPresentationElement(owner)) {
|
|
878
|
+
return commitPresentationMutation(state, () => [{ kind: "node.update", element: owner }]);
|
|
879
|
+
}
|
|
880
|
+
return null;
|
|
881
|
+
}
|
|
882
|
+
|
|
883
|
+
function commitPresentationMutation(
|
|
884
|
+
state: CompositeArtifactState<ReferencePresentation>,
|
|
885
|
+
commands: (result: unknown) => Parameters<typeof encodePresentationIncrementalCommands>[0],
|
|
886
|
+
): PreparedCompositeMutation {
|
|
887
|
+
return {
|
|
888
|
+
commit(result) {
|
|
889
|
+
const batch = commands(result);
|
|
890
|
+
if (batch.length === 0) return false;
|
|
891
|
+
const session = state.native;
|
|
892
|
+
if (!(session instanceof NativePresentationSession)) {
|
|
893
|
+
throw new TypeError("Expected native presentation session");
|
|
894
|
+
}
|
|
895
|
+
const before = session.revision();
|
|
896
|
+
session.applyCommands(encodePresentationIncrementalCommands(batch, state.namespace));
|
|
897
|
+
return session.revision() > before;
|
|
898
|
+
},
|
|
899
|
+
};
|
|
900
|
+
}
|
|
901
|
+
|
|
902
|
+
function isPresentationElement(value: unknown): value is PresentationElement {
|
|
903
|
+
return (
|
|
904
|
+
value instanceof PresentationShape ||
|
|
905
|
+
value instanceof PresentationChart ||
|
|
906
|
+
value instanceof PresentationImage ||
|
|
907
|
+
value instanceof PresentationTable ||
|
|
908
|
+
value instanceof PresentationGroup
|
|
909
|
+
);
|
|
910
|
+
}
|
|
911
|
+
|
|
912
|
+
function findPresentationTextOwner(
|
|
913
|
+
presentation: ReferencePresentation,
|
|
914
|
+
text: PresentationText,
|
|
915
|
+
): { kind: "notes"; slide: Slide } | { kind: "node"; element: PresentationElement } | null {
|
|
916
|
+
const visit = (element: PresentationElement): PresentationElement | null => {
|
|
917
|
+
if (element instanceof PresentationShape && element.text === text) return element;
|
|
918
|
+
if (element instanceof PresentationGroup) {
|
|
919
|
+
for (const child of element.children) {
|
|
920
|
+
const match = visit(child);
|
|
921
|
+
if (match) return match;
|
|
922
|
+
}
|
|
923
|
+
}
|
|
924
|
+
if (element instanceof PresentationTable) {
|
|
925
|
+
if (element.rows.some((row) => row.some((cell) => cell?.text === text))) return element;
|
|
926
|
+
}
|
|
927
|
+
return null;
|
|
928
|
+
};
|
|
929
|
+
for (const slide of presentation.slides.items) {
|
|
930
|
+
if (slide.notes === text) return { kind: "notes", slide };
|
|
931
|
+
for (const element of slide.elements) {
|
|
932
|
+
const match = visit(element);
|
|
933
|
+
if (match) return { kind: "node", element: match };
|
|
934
|
+
}
|
|
935
|
+
}
|
|
936
|
+
return null;
|
|
937
|
+
}
|
|
938
|
+
|
|
939
|
+
function captureSpreadsheetAuxiliary(workbook: ReferenceWorkbook): unknown {
|
|
940
|
+
const value = LOSS_PRESERVATION.get(workbook);
|
|
941
|
+
return value ? structuredClone(value) : undefined;
|
|
942
|
+
}
|
|
943
|
+
|
|
944
|
+
function restoreSpreadsheetAuxiliary(workbook: ReferenceWorkbook, value: unknown): void {
|
|
945
|
+
if (value)
|
|
946
|
+
LOSS_PRESERVATION.set(workbook, value as NonNullable<ReturnType<typeof LOSS_PRESERVATION.get>>);
|
|
947
|
+
}
|
|
948
|
+
|
|
949
|
+
function captureDocumentAuxiliary(document: ReferenceDocument): unknown {
|
|
950
|
+
const value = DOCUMENT_LOSS_PRESERVATION.get(document);
|
|
951
|
+
return value ? structuredClone(value) : undefined;
|
|
952
|
+
}
|
|
953
|
+
|
|
954
|
+
function restoreDocumentAuxiliary(document: ReferenceDocument, value: unknown): void {
|
|
955
|
+
if (value) {
|
|
956
|
+
DOCUMENT_LOSS_PRESERVATION.set(
|
|
957
|
+
document,
|
|
958
|
+
value as NonNullable<ReturnType<typeof DOCUMENT_LOSS_PRESERVATION.get>>,
|
|
959
|
+
);
|
|
960
|
+
}
|
|
961
|
+
}
|
|
962
|
+
|
|
963
|
+
function capturePresentationAuxiliary(presentation: ReferencePresentation): unknown {
|
|
964
|
+
const value = presentationLossState(presentation);
|
|
965
|
+
return value ? structuredClone(value) : undefined;
|
|
966
|
+
}
|
|
967
|
+
|
|
968
|
+
function restorePresentationAuxiliary(presentation: ReferencePresentation, value: unknown): void {
|
|
969
|
+
setPresentationLossState(presentation, value as ReturnType<typeof presentationLossState>);
|
|
970
|
+
}
|
|
971
|
+
|
|
972
|
+
function rawArtifact<Root extends object>(
|
|
973
|
+
artifact: Root,
|
|
974
|
+
modality: "spreadsheet" | "document" | "presentation",
|
|
975
|
+
): Root {
|
|
976
|
+
return requireCompositeState(artifact, modality).rawRoot() as Root;
|
|
977
|
+
}
|
|
978
|
+
|
|
979
|
+
function createStaticFacade<Constructor extends Function>(
|
|
980
|
+
reference: Constructor,
|
|
981
|
+
name: string,
|
|
982
|
+
statics: Readonly<Record<string, (...args: never[]) => unknown>>,
|
|
983
|
+
): Constructor {
|
|
984
|
+
const facade = function ArtifactFacade(): never {
|
|
985
|
+
throw new TypeError(`${name} cannot be constructed directly; use ${name}.create()`);
|
|
986
|
+
};
|
|
987
|
+
Object.setPrototypeOf(facade, reference);
|
|
988
|
+
Object.defineProperty(facade, "name", { configurable: true, value: name });
|
|
989
|
+
Object.defineProperty(facade, "prototype", { value: reference.prototype });
|
|
990
|
+
for (const [key, value] of Object.entries(statics)) {
|
|
991
|
+
Object.defineProperty(facade, key, { configurable: false, enumerable: false, value });
|
|
992
|
+
}
|
|
993
|
+
return facade as unknown as Constructor;
|
|
994
|
+
}
|
|
995
|
+
|
|
996
|
+
function requireConfiguredRuntime(): ArtifactKernelRuntime {
|
|
997
|
+
if (!configuredRuntime) {
|
|
998
|
+
throw new ArtifactRuntimeError(
|
|
999
|
+
"ARTIFACT_RUNTIME_UNAVAILABLE",
|
|
1000
|
+
"No exact artifact runtime is configured; host bootstrap must call configureArtifactRuntime()",
|
|
1001
|
+
);
|
|
1002
|
+
}
|
|
1003
|
+
return configuredRuntime;
|
|
1004
|
+
}
|
|
1005
|
+
|
|
1006
|
+
function envelopeCommandCount(bytes: Uint8Array): number {
|
|
1007
|
+
if (bytes.byteLength < 16) throw new TypeError("Native command envelope is truncated");
|
|
1008
|
+
return new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength).getUint32(12, true);
|
|
1009
|
+
}
|
|
1010
|
+
|
|
1011
|
+
function randomNamespace(): bigint {
|
|
1012
|
+
const words = crypto.getRandomValues(new Uint32Array(2));
|
|
1013
|
+
const namespace = (BigInt(words[0]!) << 32n) | BigInt(words[1]!);
|
|
1014
|
+
return namespace === 0n ? randomNamespace() : namespace;
|
|
1015
|
+
}
|
|
1016
|
+
|
|
1017
|
+
function u64Hex(value: bigint): string {
|
|
1018
|
+
if (value <= 0n || value > 0xffff_ffff_ffff_ffffn) {
|
|
1019
|
+
throw new RangeError("Artifact namespace must be a nonzero u64");
|
|
1020
|
+
}
|
|
1021
|
+
return value.toString(16).padStart(16, "0");
|
|
1022
|
+
}
|