@embedpdf/plugin-form 3.0.0-next.10 → 3.0.0-next.12

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,485 @@
1
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
+ let _embedpdf_core_acrojs = require("@embedpdf/core-acrojs");
3
+ //#region src/scripting.ts
4
+ const refKey = (ref) => ref.kind === "objectNumber" ? `obj:${ref.fieldObjectNumber}` : `fqn:${ref.name}`;
5
+ const sameRef = (left, right) => refKey(left) === refKey(right);
6
+ const cloneValue = (value) => Array.isArray(value) ? [...value] : value;
7
+ const sameValue = (left, right) => Array.isArray(left) && Array.isArray(right) ? left.length === right.length && left.every((value, index) => value === right[index]) : left === right;
8
+ function cloneFields(fields) {
9
+ return fields.map((field) => ({
10
+ ...field,
11
+ ref: { ...field.ref },
12
+ value: cloneValue(field.value),
13
+ defaultValue: cloneValue(field.defaultValue),
14
+ ...field.options ? { options: field.options.map((option) => ({ ...option })) } : {}
15
+ }));
16
+ }
17
+ function fieldByRef(fields, ref) {
18
+ return fields.find((field) => sameRef(field.ref, ref));
19
+ }
20
+ function snapshotField(snapshot, ref) {
21
+ return snapshot.fields.find((field) => sameRef(field.ref, ref));
22
+ }
23
+ function scriptValueFromFormValue(field, value) {
24
+ if (field.family === "text" && value.type === "text") return value.value;
25
+ if ((field.family === "checkbox" || field.family === "radio") && value.type === "toggle") return value.state ?? "Off";
26
+ if (field.family === "combobox" && value.type === "choice") return value.values[0] ?? "";
27
+ if (field.family === "listbox" && value.type === "choice") return [...value.values];
28
+ throw new Error(`Form value type '${value.type}' does not match field family '${field.family}'`);
29
+ }
30
+ function formValueFromScriptValue(field) {
31
+ switch (field.family) {
32
+ case "text": return {
33
+ type: "text",
34
+ value: String(field.value ?? "")
35
+ };
36
+ case "checkbox":
37
+ case "radio": return {
38
+ type: "toggle",
39
+ state: field.value === null || field.value === void 0 || String(field.value) === "Off" ? null : String(field.value)
40
+ };
41
+ case "combobox": return {
42
+ type: "choice",
43
+ values: Array.isArray(field.value) ? field.value.slice(0, 1) : [String(field.value ?? "")]
44
+ };
45
+ case "listbox": return {
46
+ type: "choice",
47
+ values: Array.isArray(field.value) ? [...field.value] : [String(field.value ?? "")]
48
+ };
49
+ default: return null;
50
+ }
51
+ }
52
+ function applyEffects(overlay, effects) {
53
+ for (const effect of effects) {
54
+ if (effect.kind === "reset") {
55
+ for (const ref of effect.refs) {
56
+ const field = fieldByRef(overlay.fields, ref);
57
+ if (!field) continue;
58
+ field.value = cloneValue(field.defaultValue);
59
+ overlay.resetKeys.add(refKey(ref));
60
+ }
61
+ continue;
62
+ }
63
+ const field = fieldByRef(overlay.fields, effect.ref);
64
+ if (!field) continue;
65
+ const key = refKey(effect.ref);
66
+ if (effect.kind === "setValue") {
67
+ field.value = scriptValueFromFormValue(field, effect.value);
68
+ overlay.resetKeys.delete(key);
69
+ } else if (effect.kind === "setDisplay") field.display = effect.display;
70
+ else overlay.appearances.set(key, {
71
+ ref: effect.ref,
72
+ text: effect.text
73
+ });
74
+ }
75
+ }
76
+ function canonicalEffects(overlay) {
77
+ const effects = [];
78
+ const resets = [];
79
+ for (const field of overlay.fields) {
80
+ const original = fieldByRef(overlay.original, field.ref);
81
+ if (!original) continue;
82
+ if (!sameValue(original.value, field.value)) {
83
+ const key = refKey(field.ref);
84
+ if (overlay.resetKeys.has(key) && sameValue(field.value, field.defaultValue)) resets.push(field.ref);
85
+ else {
86
+ const value = formValueFromScriptValue(field);
87
+ if (value) effects.push({
88
+ kind: "setValue",
89
+ ref: field.ref,
90
+ value
91
+ });
92
+ }
93
+ }
94
+ if (original.display !== field.display) effects.push({
95
+ kind: "setDisplay",
96
+ ref: field.ref,
97
+ display: field.display
98
+ });
99
+ }
100
+ if (resets.length > 0) effects.unshift({
101
+ kind: "reset",
102
+ refs: resets
103
+ });
104
+ effects.push(...Array.from(overlay.appearances.values(), ({ ref, text }) => ({
105
+ kind: "setAppearanceText",
106
+ ref,
107
+ text
108
+ })));
109
+ return effects;
110
+ }
111
+ function scriptError(message) {
112
+ return {
113
+ kind: "invalid-output",
114
+ message
115
+ };
116
+ }
117
+ function utf8Length(value) {
118
+ let length = 0;
119
+ for (let index = 0; index < value.length; index += 1) {
120
+ const code = value.charCodeAt(index);
121
+ if (code < 128) length += 1;
122
+ else if (code < 2048) length += 2;
123
+ else if (code >= 55296 && code <= 56319 && index + 1 < value.length) {
124
+ length += 4;
125
+ index += 1;
126
+ } else length += 3;
127
+ }
128
+ return length;
129
+ }
130
+ function pageNumberFor(meta, field) {
131
+ const pon = field.widgets.find((widget) => widget.pageObjectNumber > 0)?.pageObjectNumber;
132
+ if (!meta || pon === void 0) return 0;
133
+ const index = meta.pages.findIndex((page) => page.pageObjectNumber === pon);
134
+ return Math.max(0, index);
135
+ }
136
+ function statusFromEffects(result) {
137
+ if (result.results.some(({ status }) => status === "failed" || status === "skipped")) return "failed";
138
+ if (result.results.some(({ status }) => status === "rejected")) return "failed";
139
+ return result.results.some(({ status }) => status === "applied") ? "applied" : "unchanged";
140
+ }
141
+ var FormScriptingController = class {
142
+ constructor(options) {
143
+ this.options = options;
144
+ this.disposed = false;
145
+ this.transaction = options.transaction.bind(options);
146
+ this.transactionBudget = options.budget;
147
+ }
148
+ /** The realm belongs to its OWNER (the actions plugin, or the caller that
149
+ * minted a detached one) — this only fences further transactions. */
150
+ dispose() {
151
+ this.disposed = true;
152
+ }
153
+ async commit(ref, proposed) {
154
+ return this.transact(ref, proposed);
155
+ }
156
+ /** Execute one originating widget's activation action (`/A`, including `/Next`). */
157
+ async activate(ref, action) {
158
+ return this.transact(ref, void 0, action);
159
+ }
160
+ /** Run lazy document boot plus the `/CO` chain without a user field change.
161
+ * The anchor field resolves INSIDE the transaction (undefined ref). */
162
+ async recalculate() {
163
+ return this.transact(void 0);
164
+ }
165
+ async transact(refInput, proposed, activation) {
166
+ if (this.disposed) throw new Error("Form scripting controller is disposed");
167
+ return this.transaction((txn) => this.transactBody(txn, refInput, proposed, activation));
168
+ }
169
+ async transactBody(txn, refInput, proposed, activation) {
170
+ const snapshot = await this.options.doc.forms.list();
171
+ const ref = refInput ?? snapshot.calculationOrder.find((candidate) => candidate !== null && snapshotField(snapshot, candidate) !== void 0) ?? snapshot.fields[0]?.ref;
172
+ if (!ref) return {
173
+ status: "unchanged",
174
+ scripted: true,
175
+ effectsResult: null,
176
+ uiEffects: [],
177
+ diagnostics: []
178
+ };
179
+ const target = snapshotField(snapshot, ref);
180
+ if (!target) return this.failed([], [], scriptError(`Form field '${refKey(ref)}' no longer exists`));
181
+ const original = (0, _embedpdf_core_acrojs.scriptFieldsFromSnapshot)(snapshot);
182
+ const overlay = {
183
+ original,
184
+ fields: cloneFields(original),
185
+ resetKeys: /* @__PURE__ */ new Set(),
186
+ appearances: /* @__PURE__ */ new Map()
187
+ };
188
+ const targetInput = fieldByRef(overlay.fields, ref);
189
+ if (!targetInput) return this.failed([], [], scriptError(`Form field '${refKey(ref)}' has no script view`));
190
+ const hasProposedValue = proposed !== void 0;
191
+ let proposedValue = cloneValue(targetInput.value);
192
+ if (proposed) try {
193
+ proposedValue = scriptValueFromFormValue(targetInput, proposed);
194
+ } catch (error) {
195
+ return this.failed([], [], scriptError(error instanceof Error ? error.message : String(error)));
196
+ }
197
+ const uiEffects = [];
198
+ const diagnostics = [];
199
+ const pageNumber = pageNumberFor(this.options.document(), target);
200
+ const budget = this.transactionBudget ?? _embedpdf_core_acrojs.DEFAULT_SCRIPT_BUDGET;
201
+ let executionMs = 0;
202
+ let aggregateOutputSize = 0;
203
+ const consume = (output, phase) => {
204
+ aggregateOutputSize += utf8Length(JSON.stringify(output));
205
+ uiEffects.push(...output.uiEffects.map((effect) => ({
206
+ ...effect,
207
+ phase
208
+ })));
209
+ diagnostics.push(...output.diagnostics);
210
+ if (aggregateOutputSize > budget.maxOutputBytes) return {
211
+ kind: "budget",
212
+ message: `Form script transaction output exceeded ${budget.maxOutputBytes} bytes`
213
+ };
214
+ return output.error ?? null;
215
+ };
216
+ const remainingBudget = () => {
217
+ const remaining = budget.maxExecutionMs - executionMs;
218
+ return remaining <= 0 ? null : {
219
+ ...budget,
220
+ maxExecutionMs: remaining
221
+ };
222
+ };
223
+ const world = (fields, event) => ({
224
+ fields,
225
+ pageNumber,
226
+ event
227
+ });
228
+ const run = async (source, input) => {
229
+ const remaining = remainingBudget();
230
+ if (!remaining) return { error: {
231
+ kind: "budget",
232
+ message: "Form script transaction timed out"
233
+ } };
234
+ let output;
235
+ try {
236
+ const startedAt = Date.now();
237
+ output = await txn.run(source, input, remaining);
238
+ executionMs += Date.now() - startedAt;
239
+ } catch (error) {
240
+ return { error: scriptError(error instanceof Error ? error.message : String(error)) };
241
+ }
242
+ const error = consume(output, "user");
243
+ return error ? { error } : { output };
244
+ };
245
+ {
246
+ let boot = null;
247
+ try {
248
+ boot = await txn.boot(world(overlay.fields, { kind: "name-tree-boot" }), budget);
249
+ } catch (error) {
250
+ diagnostics.push({
251
+ code: "script-error",
252
+ message: `Document boot script failed (continuing without it): ${error instanceof Error ? error.message : String(error)}`
253
+ });
254
+ }
255
+ if (boot) {
256
+ const bootError = consume(boot, "boot");
257
+ if (!bootError) applyEffects(overlay, boot.formEffects);
258
+ else diagnostics.push({
259
+ code: "script-error",
260
+ message: `Document boot script failed (continuing without it): ${bootError.message}`
261
+ });
262
+ }
263
+ }
264
+ const bootEffects = canonicalEffects(overlay);
265
+ if (activation) {
266
+ let program;
267
+ try {
268
+ program = (0, _embedpdf_core_acrojs.javaScriptProgramFromActionTree)(activation);
269
+ } catch (error) {
270
+ return this.failed(uiEffects, diagnostics, scriptError(error instanceof Error ? error.message : String(error)));
271
+ }
272
+ if (program) {
273
+ const activated = await run(program, world(overlay.fields, {
274
+ kind: "widget-activate",
275
+ target: ref,
276
+ source: ref,
277
+ value: targetInput.value
278
+ }));
279
+ if (activated.error) return this.failed(uiEffects, diagnostics, activated.error);
280
+ applyEffects(overlay, activated.output.formEffects);
281
+ }
282
+ }
283
+ if (!activation && hasProposedValue && target.actions?.keystroke && target.family === "text") {
284
+ let program;
285
+ try {
286
+ program = (0, _embedpdf_core_acrojs.javaScriptProgramFromActionTree)(target.actions.keystroke);
287
+ } catch (error) {
288
+ return this.failed(uiEffects, diagnostics, scriptError(error instanceof Error ? error.message : String(error)));
289
+ }
290
+ if (program) {
291
+ const oldValue = String(targetInput.value ?? "");
292
+ const typing = await run(program, world(overlay.fields, {
293
+ kind: "field-keystroke",
294
+ target: ref,
295
+ source: ref,
296
+ value: oldValue,
297
+ change: String(proposedValue ?? ""),
298
+ selStart: 0,
299
+ selEnd: oldValue.length,
300
+ willCommit: false
301
+ }));
302
+ if (typing.error && typing.error.kind !== "exception") return this.failed(uiEffects, diagnostics, typing.error);
303
+ if (typing.error) diagnostics.push({
304
+ code: "script-error",
305
+ message: `Keystroke script failed (kept the typed value): ${typing.error.message}`
306
+ });
307
+ else {
308
+ if (!typing.output.event.rc) return this.finishRejected(bootEffects, uiEffects, diagnostics);
309
+ applyEffects(overlay, typing.output.formEffects);
310
+ const event = typing.output.event;
311
+ const base = String(event.value ?? "");
312
+ proposedValue = base.slice(0, event.selStart) + event.change + base.slice(Math.max(event.selStart, event.selEnd));
313
+ }
314
+ const commit = await run(program, world(overlay.fields, {
315
+ kind: "field-keystroke",
316
+ target: ref,
317
+ source: ref,
318
+ value: proposedValue,
319
+ change: "",
320
+ selStart: 0,
321
+ selEnd: 0,
322
+ willCommit: true
323
+ }));
324
+ if (commit.error && commit.error.kind !== "exception") return this.failed(uiEffects, diagnostics, commit.error);
325
+ if (commit.error) diagnostics.push({
326
+ code: "script-error",
327
+ message: `Keystroke commit script failed (kept the typed value): ${commit.error.message}`
328
+ });
329
+ else {
330
+ if (!commit.output.event.rc) return this.finishRejected(bootEffects, uiEffects, diagnostics);
331
+ applyEffects(overlay, commit.output.formEffects);
332
+ proposedValue = cloneValue(commit.output.event.value);
333
+ }
334
+ }
335
+ }
336
+ if (!activation && hasProposedValue) {
337
+ targetInput.value = cloneValue(proposedValue);
338
+ overlay.resetKeys.delete(refKey(ref));
339
+ }
340
+ if (!activation && hasProposedValue && target.actions?.validate) {
341
+ let program;
342
+ try {
343
+ program = (0, _embedpdf_core_acrojs.javaScriptProgramFromActionTree)(target.actions.validate);
344
+ } catch (error) {
345
+ return this.failed(uiEffects, diagnostics, scriptError(error instanceof Error ? error.message : String(error)));
346
+ }
347
+ if (program) {
348
+ const validation = await run(program, world(overlay.fields, {
349
+ kind: "field-validate",
350
+ target: ref,
351
+ source: ref,
352
+ value: proposedValue,
353
+ willCommit: true
354
+ }));
355
+ if (validation.error && validation.error.kind !== "exception") return this.failed(uiEffects, diagnostics, validation.error);
356
+ if (validation.error) diagnostics.push({
357
+ code: "script-error",
358
+ message: `Validate script failed (accepted the value): ${validation.error.message}`
359
+ });
360
+ else {
361
+ if (!validation.output.event.rc) return this.finishRejected(bootEffects, uiEffects, diagnostics);
362
+ targetInput.value = cloneValue(validation.output.event.value);
363
+ applyEffects(overlay, validation.output.formEffects);
364
+ }
365
+ }
366
+ }
367
+ const formatRefs = !activation && hasProposedValue ? [ref] : [];
368
+ for (const calculationRef of activation ? [] : snapshot.calculationOrder) {
369
+ if (!calculationRef) continue;
370
+ const calculated = snapshotField(snapshot, calculationRef);
371
+ const tree = calculated?.actions?.calculate;
372
+ if (!calculated || !tree) continue;
373
+ let program;
374
+ try {
375
+ program = (0, _embedpdf_core_acrojs.javaScriptProgramFromActionTree)(tree);
376
+ } catch (error) {
377
+ return this.failed(uiEffects, diagnostics, scriptError(error instanceof Error ? error.message : String(error)));
378
+ }
379
+ const calculatedInput = fieldByRef(overlay.fields, calculationRef);
380
+ if (program && calculatedInput) {
381
+ const calculation = await run(program, world(overlay.fields, {
382
+ kind: "field-calculate",
383
+ target: calculationRef,
384
+ ...hasProposedValue ? { source: ref } : {},
385
+ value: calculatedInput.value
386
+ }));
387
+ if (calculation.error && calculation.error.kind !== "exception") return this.failed(uiEffects, diagnostics, calculation.error);
388
+ if (calculation.error) diagnostics.push({
389
+ code: "script-error",
390
+ message: `Calculate script failed (field left unchanged): ${calculation.error.message}`
391
+ });
392
+ else applyEffects(overlay, calculation.output.formEffects);
393
+ }
394
+ if (!formatRefs.some((candidate) => sameRef(candidate, calculationRef))) formatRefs.push(calculationRef);
395
+ }
396
+ for (const formatRef of formatRefs) {
397
+ const field = snapshotField(snapshot, formatRef);
398
+ const tree = field?.actions?.format;
399
+ const overlayField = fieldByRef(overlay.fields, formatRef);
400
+ if (!field || !tree || !overlayField) continue;
401
+ let program;
402
+ try {
403
+ program = (0, _embedpdf_core_acrojs.javaScriptProgramFromActionTree)(tree);
404
+ } catch (error) {
405
+ return this.failed(uiEffects, diagnostics, scriptError(error instanceof Error ? error.message : String(error)));
406
+ }
407
+ if (!program) continue;
408
+ const format = await run(program, world(overlay.fields, {
409
+ kind: "field-format",
410
+ target: formatRef,
411
+ ...hasProposedValue ? { source: ref } : {},
412
+ value: overlayField.value
413
+ }));
414
+ if (format.error && format.error.kind !== "exception") return this.failed(uiEffects, diagnostics, format.error);
415
+ if (format.error) {
416
+ diagnostics.push({
417
+ code: "script-error",
418
+ message: `Format script failed (kept the raw value): ${format.error.message}`
419
+ });
420
+ continue;
421
+ }
422
+ applyEffects(overlay, format.output.formEffects);
423
+ }
424
+ const effects = canonicalEffects(overlay);
425
+ if (effects.length + uiEffects.length > budget.maxEffects) return this.failed(uiEffects, diagnostics, {
426
+ kind: "budget",
427
+ message: `Form script transaction exceeded ${budget.maxEffects} effects`
428
+ });
429
+ if (effects.length === 0) return {
430
+ status: "unchanged",
431
+ scripted: true,
432
+ effectsResult: null,
433
+ uiEffects,
434
+ diagnostics
435
+ };
436
+ if (!this.options.doc.forms.applyEffects) return this.failed(uiEffects, diagnostics, scriptError("This engine does not support batched form effects"));
437
+ const effectsResult = await this.options.doc.forms.applyEffects(effects);
438
+ const status = statusFromEffects(effectsResult);
439
+ return {
440
+ status,
441
+ scripted: true,
442
+ effectsResult,
443
+ uiEffects,
444
+ diagnostics,
445
+ ...status === "failed" ? { error: scriptError("One or more native form effects failed") } : {}
446
+ };
447
+ }
448
+ failed(uiEffects, diagnostics, error) {
449
+ return {
450
+ status: "failed",
451
+ scripted: true,
452
+ effectsResult: null,
453
+ uiEffects,
454
+ diagnostics,
455
+ error
456
+ };
457
+ }
458
+ async finishRejected(bootEffects, uiEffects, diagnostics) {
459
+ if (bootEffects.length === 0) return {
460
+ status: "rejected",
461
+ scripted: true,
462
+ effectsResult: null,
463
+ uiEffects,
464
+ diagnostics
465
+ };
466
+ if (!this.options.doc.forms.applyEffects) return this.failed(uiEffects, diagnostics, scriptError("Batched form effects are unavailable"));
467
+ const effectsResult = await this.options.doc.forms.applyEffects(bootEffects);
468
+ if (statusFromEffects(effectsResult) === "failed") return this.failed(uiEffects, diagnostics, scriptError("A name-tree boot effect failed"));
469
+ return {
470
+ status: "rejected",
471
+ scripted: true,
472
+ effectsResult,
473
+ uiEffects,
474
+ diagnostics
475
+ };
476
+ }
477
+ };
478
+ function createFormScriptingController(options) {
479
+ return new FormScriptingController(options);
480
+ }
481
+ //#endregion
482
+ exports.FormScriptingController = FormScriptingController;
483
+ exports.createFormScriptingController = createFormScriptingController;
484
+
485
+ //# sourceMappingURL=scripting.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scripting.cjs","names":["DEFAULT_SCRIPT_BUDGET"],"sources":["../src/scripting.ts"],"sourcesContent":["import type {\n DocumentHandle,\n FormEffect,\n FormEffectsResult,\n FormFieldDTO,\n FormFieldRef,\n FormFieldValue,\n FormSnapshot,\n PdfActionTree,\n} from '@embedpdf/engine-core/runtime';\nimport {\n DEFAULT_SCRIPT_BUDGET,\n javaScriptProgramFromActionTree,\n scriptFieldsFromSnapshot,\n type ScriptBudget,\n type ScriptDiagnostic,\n type ScriptExecutionError,\n type ScriptFieldInput,\n type ScriptOutput,\n type ScriptTransaction,\n type ScriptUiEffect,\n type ScriptValue,\n type ScriptWorldInput,\n} from '@embedpdf/core-acrojs';\nimport type { DocumentMeta } from '@embedpdf/core';\n\nimport type { FormCommitResult, FormUiEffect } from './types';\n\ninterface Overlay {\n original: ScriptFieldInput[];\n fields: ScriptFieldInput[];\n resetKeys: Set<string>;\n appearances: Map<string, { ref: FormFieldRef; text: string }>;\n}\n\n/**\n * The controller never owns a realm. It rides a realm PORT — this document's\n * own (the actions plugin's per-document host) or a detached one minted by\n * the actions plugin for a document that is not displayed (stamp's\n * asset documents). Either way the owner disposes the realm; `dispose()`\n * here only fences further transactions.\n */\nexport interface FormScriptingControllerOptions {\n doc: DocumentHandle;\n document(): DocumentMeta | null;\n /** The realm's transaction port ({@link ScriptTransaction}). The K/V/C/F\n * pipeline runs WHOLLY inside one transaction: snapshot fetch, every\n * pass, and the engine commit — the commit-inside-the-boundary law. */\n transaction<T>(body: (txn: ScriptTransaction) => Promise<T>): Promise<T>;\n /** The transaction aggregate (output bytes, wall-clock across passes);\n * the realm owner hands over the same budget its runs enforce. */\n budget?: ScriptBudget;\n}\n\nconst refKey = (ref: FormFieldRef): string =>\n ref.kind === 'objectNumber' ? `obj:${ref.fieldObjectNumber}` : `fqn:${ref.name}`;\n\nconst sameRef = (left: FormFieldRef, right: FormFieldRef): boolean =>\n refKey(left) === refKey(right);\n\nconst cloneValue = (value: ScriptValue): ScriptValue => (Array.isArray(value) ? [...value] : value);\n\nconst sameValue = (left: ScriptValue, right: ScriptValue): boolean =>\n Array.isArray(left) && Array.isArray(right)\n ? left.length === right.length && left.every((value, index) => value === right[index])\n : left === right;\n\nfunction cloneFields(fields: ScriptFieldInput[]): ScriptFieldInput[] {\n return fields.map((field) => ({\n ...field,\n ref: { ...field.ref },\n value: cloneValue(field.value),\n defaultValue: cloneValue(field.defaultValue),\n ...(field.options ? { options: field.options.map((option) => ({ ...option })) } : {}),\n }));\n}\n\nfunction fieldByRef<T extends { ref: FormFieldRef }>(\n fields: T[],\n ref: FormFieldRef,\n): T | undefined {\n return fields.find((field) => sameRef(field.ref, ref));\n}\n\nfunction snapshotField(snapshot: FormSnapshot, ref: FormFieldRef): FormFieldDTO | undefined {\n return snapshot.fields.find((field) => sameRef(field.ref, ref));\n}\n\nfunction scriptValueFromFormValue(field: ScriptFieldInput, value: FormFieldValue): ScriptValue {\n if (field.family === 'text' && value.type === 'text') return value.value;\n if ((field.family === 'checkbox' || field.family === 'radio') && value.type === 'toggle') {\n return value.state ?? 'Off';\n }\n if (field.family === 'combobox' && value.type === 'choice') return value.values[0] ?? '';\n if (field.family === 'listbox' && value.type === 'choice') return [...value.values];\n throw new Error(`Form value type '${value.type}' does not match field family '${field.family}'`);\n}\n\nfunction formValueFromScriptValue(field: ScriptFieldInput): FormFieldValue | null {\n switch (field.family) {\n case 'text':\n return { type: 'text', value: String(field.value ?? '') };\n case 'checkbox':\n case 'radio':\n return {\n type: 'toggle',\n state:\n field.value === null || field.value === undefined || String(field.value) === 'Off'\n ? null\n : String(field.value),\n };\n case 'combobox':\n return {\n type: 'choice',\n values: Array.isArray(field.value) ? field.value.slice(0, 1) : [String(field.value ?? '')],\n };\n case 'listbox':\n return {\n type: 'choice',\n values: Array.isArray(field.value) ? [...field.value] : [String(field.value ?? '')],\n };\n default:\n return null;\n }\n}\n\nfunction applyEffects(overlay: Overlay, effects: FormEffect[]): void {\n for (const effect of effects) {\n if (effect.kind === 'reset') {\n for (const ref of effect.refs) {\n const field = fieldByRef(overlay.fields, ref);\n if (!field) continue;\n field.value = cloneValue(field.defaultValue);\n overlay.resetKeys.add(refKey(ref));\n }\n continue;\n }\n\n const field = fieldByRef(overlay.fields, effect.ref);\n if (!field) continue;\n const key = refKey(effect.ref);\n if (effect.kind === 'setValue') {\n field.value = scriptValueFromFormValue(field, effect.value);\n overlay.resetKeys.delete(key);\n } else if (effect.kind === 'setDisplay') {\n field.display = effect.display;\n } else {\n overlay.appearances.set(key, { ref: effect.ref, text: effect.text });\n }\n }\n}\n\nfunction canonicalEffects(overlay: Overlay): FormEffect[] {\n const effects: FormEffect[] = [];\n const resets: FormFieldRef[] = [];\n for (const field of overlay.fields) {\n const original = fieldByRef(overlay.original, field.ref);\n if (!original) continue;\n if (!sameValue(original.value, field.value)) {\n const key = refKey(field.ref);\n if (overlay.resetKeys.has(key) && sameValue(field.value, field.defaultValue)) {\n resets.push(field.ref);\n } else {\n const value = formValueFromScriptValue(field);\n if (value) effects.push({ kind: 'setValue', ref: field.ref, value });\n }\n }\n if (original.display !== field.display) {\n effects.push({ kind: 'setDisplay', ref: field.ref, display: field.display });\n }\n }\n if (resets.length > 0) effects.unshift({ kind: 'reset', refs: resets });\n effects.push(\n ...Array.from(overlay.appearances.values(), ({ ref, text }) => ({\n kind: 'setAppearanceText' as const,\n ref,\n text,\n })),\n );\n return effects;\n}\n\nfunction scriptError(message: string): ScriptExecutionError {\n return { kind: 'invalid-output', message };\n}\n\nfunction utf8Length(value: string): number {\n let length = 0;\n for (let index = 0; index < value.length; index += 1) {\n const code = value.charCodeAt(index);\n if (code < 0x80) length += 1;\n else if (code < 0x800) length += 2;\n else if (code >= 0xd800 && code <= 0xdbff && index + 1 < value.length) {\n length += 4;\n index += 1;\n } else length += 3;\n }\n return length;\n}\n\nfunction pageNumberFor(meta: DocumentMeta | null, field: FormFieldDTO): number {\n const pon = field.widgets.find((widget) => widget.pageObjectNumber > 0)?.pageObjectNumber;\n if (!meta || pon === undefined) return 0;\n const index = meta.pages.findIndex((page) => page.pageObjectNumber === pon);\n return Math.max(0, index);\n}\n\nfunction statusFromEffects(result: FormEffectsResult): FormCommitResult['status'] {\n if (result.results.some(({ status }) => status === 'failed' || status === 'skipped')) {\n return 'failed';\n }\n if (result.results.some(({ status }) => status === 'rejected')) return 'failed';\n return result.results.some(({ status }) => status === 'applied') ? 'applied' : 'unchanged';\n}\n\nexport class FormScriptingController {\n private disposed = false;\n private readonly transaction: <T>(body: (txn: ScriptTransaction) => Promise<T>) => Promise<T>;\n private readonly transactionBudget: ScriptBudget | undefined;\n\n constructor(private readonly options: FormScriptingControllerOptions) {\n this.transaction = options.transaction.bind(options);\n this.transactionBudget = options.budget;\n }\n\n /** The realm belongs to its OWNER (the actions plugin, or the caller that\n * minted a detached one) — this only fences further transactions. */\n dispose(): void {\n this.disposed = true;\n }\n\n async commit(ref: FormFieldRef, proposed: FormFieldValue): Promise<FormCommitResult> {\n return this.transact(ref, proposed);\n }\n\n /** Execute one originating widget's activation action (`/A`, including `/Next`). */\n async activate(ref: FormFieldRef, action: PdfActionTree): Promise<FormCommitResult> {\n return this.transact(ref, undefined, action);\n }\n\n /** Run lazy document boot plus the `/CO` chain without a user field change.\n * The anchor field resolves INSIDE the transaction (undefined ref). */\n async recalculate(): Promise<FormCommitResult> {\n return this.transact(undefined);\n }\n\n private async transact(\n refInput: FormFieldRef | undefined,\n proposed?: FormFieldValue,\n activation?: PdfActionTree,\n ): Promise<FormCommitResult> {\n if (this.disposed) throw new Error('Form scripting controller is disposed');\n // EVERYTHING inside the realm transaction — snapshot fetch, every pass,\n // the engine commit — so the next transaction reads post-commit truth.\n return this.transaction((txn) => this.transactBody(txn, refInput, proposed, activation));\n }\n\n private async transactBody(\n txn: ScriptTransaction,\n refInput: FormFieldRef | undefined,\n proposed?: FormFieldValue,\n activation?: PdfActionTree,\n ): Promise<FormCommitResult> {\n const snapshot = await this.options.doc.forms.list();\n // Recalculate's anchor resolves HERE (first live /CO field, else the\n // first field); a zero-field document is an honest no-op.\n const ref =\n refInput ??\n snapshot.calculationOrder.find(\n (candidate): candidate is FormFieldRef =>\n candidate !== null && snapshotField(snapshot, candidate) !== undefined,\n ) ??\n snapshot.fields[0]?.ref;\n if (!ref) {\n return {\n status: 'unchanged',\n scripted: true,\n effectsResult: null,\n uiEffects: [],\n diagnostics: [],\n };\n }\n const target = snapshotField(snapshot, ref);\n if (!target) {\n return this.failed([], [], scriptError(`Form field '${refKey(ref)}' no longer exists`));\n }\n\n const original = scriptFieldsFromSnapshot(snapshot);\n const overlay: Overlay = {\n original,\n fields: cloneFields(original),\n resetKeys: new Set(),\n appearances: new Map(),\n };\n const targetInput = fieldByRef(overlay.fields, ref);\n if (!targetInput) {\n return this.failed([], [], scriptError(`Form field '${refKey(ref)}' has no script view`));\n }\n\n const hasProposedValue = proposed !== undefined;\n let proposedValue: ScriptValue = cloneValue(targetInput.value);\n if (proposed) {\n try {\n proposedValue = scriptValueFromFormValue(targetInput, proposed);\n } catch (error) {\n return this.failed(\n [],\n [],\n scriptError(error instanceof Error ? error.message : String(error)),\n );\n }\n }\n\n const uiEffects: FormUiEffect[] = [];\n const diagnostics: ScriptDiagnostic[] = [];\n const meta = this.options.document();\n // Document/identity/environment are HOST-owned now; the world carries the\n // per-field current page for `this.pageNum`.\n const pageNumber = pageNumberFor(meta, target);\n const budget = this.transactionBudget ?? DEFAULT_SCRIPT_BUDGET;\n let executionMs = 0;\n let aggregateOutputSize = 0;\n\n const consume = (\n output: ScriptOutput,\n phase: FormUiEffect['phase'],\n ): ScriptExecutionError | null => {\n aggregateOutputSize += utf8Length(JSON.stringify(output));\n // Tag every UI request with WHO asked — embedders suppress boot-phase\n // nags (Adobe's version-check alert) but show user-phase validation.\n uiEffects.push(...output.uiEffects.map((effect) => ({ ...effect, phase })));\n diagnostics.push(...output.diagnostics);\n if (aggregateOutputSize > budget.maxOutputBytes) {\n return {\n kind: 'budget',\n message: `Form script transaction output exceeded ${budget.maxOutputBytes} bytes`,\n };\n }\n return output.error ?? null;\n };\n const remainingBudget = (): ScriptBudget | null => {\n const remaining = budget.maxExecutionMs - executionMs;\n return remaining <= 0 ? null : { ...budget, maxExecutionMs: remaining };\n };\n const world = (\n fields: ScriptFieldInput[],\n event: ScriptWorldInput['event'],\n ): ScriptWorldInput => ({\n fields,\n pageNumber,\n event,\n });\n const run = async (\n source: string,\n input: ScriptWorldInput,\n ): Promise<{ output?: ScriptOutput; error?: ScriptExecutionError }> => {\n const remaining = remainingBudget();\n if (!remaining) {\n return { error: { kind: 'budget', message: 'Form script transaction timed out' } };\n }\n let output: ScriptOutput;\n try {\n const startedAt = Date.now();\n output = await txn.run(source, input, remaining);\n executionMs += Date.now() - startedAt;\n } catch (error) {\n return {\n error: scriptError(error instanceof Error ? error.message : String(error)),\n };\n }\n const error = consume(output, 'user');\n return error ? { error } : { output };\n };\n\n {\n // Boot runs ONCE per realm (host-owned latch) and can only ever\n // degrade, never brick — a failure surfaces a diagnostic and this\n // transaction continues from pristine state.\n let boot: ScriptOutput | null = null;\n try {\n boot = await txn.boot(world(overlay.fields, { kind: 'name-tree-boot' }), budget);\n } catch (error) {\n diagnostics.push({\n code: 'script-error',\n message: `Document boot script failed (continuing without it): ${error instanceof Error ? error.message : String(error)}`,\n });\n }\n if (boot) {\n const bootError = consume(boot, 'boot');\n if (!bootError) applyEffects(overlay, boot.formEffects);\n else {\n diagnostics.push({\n code: 'script-error',\n message: `Document boot script failed (continuing without it): ${bootError.message}`,\n });\n }\n }\n }\n\n const bootEffects = canonicalEffects(overlay);\n\n if (activation) {\n let program: string;\n try {\n program = javaScriptProgramFromActionTree(activation);\n } catch (error) {\n return this.failed(\n uiEffects,\n diagnostics,\n scriptError(error instanceof Error ? error.message : String(error)),\n );\n }\n if (program) {\n const activated = await run(\n program,\n world(overlay.fields, {\n kind: 'widget-activate',\n target: ref,\n source: ref,\n value: targetInput.value,\n }),\n );\n if (activated.error) return this.failed(uiEffects, diagnostics, activated.error);\n applyEffects(overlay, activated.output!.formEffects);\n }\n }\n\n if (!activation && hasProposedValue && target.actions?.keystroke && target.family === 'text') {\n let program: string;\n try {\n program = javaScriptProgramFromActionTree(target.actions.keystroke);\n } catch (error) {\n return this.failed(\n uiEffects,\n diagnostics,\n scriptError(error instanceof Error ? error.message : String(error)),\n );\n }\n if (program) {\n // Acrobat fires per-typing keystroke events plus one final commit\n // event. This pipeline compresses typing into ONE paste-shaped\n // replacement (Acrobat's own paste contract: the whole string rides\n // `event.change`, willCommit=false) so transform/filter scripts run,\n // then fires the Acrobat-faithful willCommit pass (the full value on\n // `event.value`, empty `change`) so AF* and commit validators see\n // what Adobe's library expects.\n const oldValue = String(targetInput.value ?? '');\n const typing = await run(\n program,\n world(overlay.fields, {\n kind: 'field-keystroke',\n target: ref,\n source: ref,\n value: oldValue,\n change: String(proposedValue ?? ''),\n selStart: 0,\n selEnd: oldValue.length,\n willCommit: false,\n }),\n );\n if (typing.error && typing.error.kind !== 'exception') {\n return this.failed(uiEffects, diagnostics, typing.error);\n }\n if (typing.error) {\n // Fault ladder: an exception is not a rejection. Keep the typed\n // value, surface a diagnostic, and let the transaction continue.\n diagnostics.push({\n code: 'script-error',\n message: `Keystroke script failed (kept the typed value): ${typing.error.message}`,\n });\n } else {\n if (!typing.output!.event.rc) {\n return this.finishRejected(bootEffects, uiEffects, diagnostics);\n }\n applyEffects(overlay, typing.output!.formEffects);\n const event = typing.output!.event;\n const base = String(event.value ?? '');\n proposedValue =\n base.slice(0, event.selStart) +\n event.change +\n base.slice(Math.max(event.selStart, event.selEnd));\n }\n const commit = await run(\n program,\n world(overlay.fields, {\n kind: 'field-keystroke',\n target: ref,\n source: ref,\n value: proposedValue,\n change: '',\n selStart: 0,\n selEnd: 0,\n willCommit: true,\n }),\n );\n if (commit.error && commit.error.kind !== 'exception') {\n return this.failed(uiEffects, diagnostics, commit.error);\n }\n if (commit.error) {\n diagnostics.push({\n code: 'script-error',\n message: `Keystroke commit script failed (kept the typed value): ${commit.error.message}`,\n });\n } else {\n if (!commit.output!.event.rc) {\n return this.finishRejected(bootEffects, uiEffects, diagnostics);\n }\n applyEffects(overlay, commit.output!.formEffects);\n proposedValue = cloneValue(commit.output!.event.value);\n }\n }\n }\n\n if (!activation && hasProposedValue) {\n targetInput.value = cloneValue(proposedValue);\n overlay.resetKeys.delete(refKey(ref));\n }\n\n if (!activation && hasProposedValue && target.actions?.validate) {\n let program: string;\n try {\n program = javaScriptProgramFromActionTree(target.actions.validate);\n } catch (error) {\n return this.failed(\n uiEffects,\n diagnostics,\n scriptError(error instanceof Error ? error.message : String(error)),\n );\n }\n if (program) {\n const validation = await run(\n program,\n world(overlay.fields, {\n kind: 'field-validate',\n target: ref,\n source: ref,\n value: proposedValue,\n willCommit: true,\n }),\n );\n if (validation.error && validation.error.kind !== 'exception') {\n return this.failed(uiEffects, diagnostics, validation.error);\n }\n if (validation.error) {\n // Fault ladder: a broken validator must not reject the value.\n diagnostics.push({\n code: 'script-error',\n message: `Validate script failed (accepted the value): ${validation.error.message}`,\n });\n } else {\n if (!validation.output!.event.rc) {\n return this.finishRejected(bootEffects, uiEffects, diagnostics);\n }\n targetInput.value = cloneValue(validation.output!.event.value);\n applyEffects(overlay, validation.output!.formEffects);\n }\n }\n }\n\n const formatRefs: FormFieldRef[] = !activation && hasProposedValue ? [ref] : [];\n for (const calculationRef of activation ? [] : snapshot.calculationOrder) {\n if (!calculationRef) continue;\n const calculated = snapshotField(snapshot, calculationRef);\n const tree = calculated?.actions?.calculate;\n if (!calculated || !tree) continue;\n let program: string;\n try {\n program = javaScriptProgramFromActionTree(tree);\n } catch (error) {\n return this.failed(\n uiEffects,\n diagnostics,\n scriptError(error instanceof Error ? error.message : String(error)),\n );\n }\n const calculatedInput = fieldByRef(overlay.fields, calculationRef);\n if (program && calculatedInput) {\n const calculation = await run(\n program,\n world(overlay.fields, {\n kind: 'field-calculate',\n target: calculationRef,\n ...(hasProposedValue ? { source: ref } : {}),\n value: calculatedInput.value,\n }),\n );\n if (calculation.error && calculation.error.kind !== 'exception') {\n return this.failed(uiEffects, diagnostics, calculation.error);\n }\n if (calculation.error) {\n // Fault ladder: this field's calculation is skipped; the /CO chain continues.\n diagnostics.push({\n code: 'script-error',\n message: `Calculate script failed (field left unchanged): ${calculation.error.message}`,\n });\n } else {\n applyEffects(overlay, calculation.output!.formEffects);\n }\n }\n if (!formatRefs.some((candidate) => sameRef(candidate, calculationRef))) {\n formatRefs.push(calculationRef);\n }\n }\n\n for (const formatRef of formatRefs) {\n const field = snapshotField(snapshot, formatRef);\n const tree = field?.actions?.format;\n const overlayField = fieldByRef(overlay.fields, formatRef);\n if (!field || !tree || !overlayField) continue;\n let program: string;\n try {\n program = javaScriptProgramFromActionTree(tree);\n } catch (error) {\n return this.failed(\n uiEffects,\n diagnostics,\n scriptError(error instanceof Error ? error.message : String(error)),\n );\n }\n if (!program) continue;\n const format = await run(\n program,\n world(overlay.fields, {\n kind: 'field-format',\n target: formatRef,\n ...(hasProposedValue ? { source: ref } : {}),\n value: overlayField.value,\n }),\n );\n if (format.error && format.error.kind !== 'exception') {\n return this.failed(uiEffects, diagnostics, format.error);\n }\n if (format.error) {\n // Fault ladder: formatting is cosmetic — skip it, keep the raw value.\n diagnostics.push({\n code: 'script-error',\n message: `Format script failed (kept the raw value): ${format.error.message}`,\n });\n continue;\n }\n applyEffects(overlay, format.output!.formEffects);\n }\n\n const effects = canonicalEffects(overlay);\n if (effects.length + uiEffects.length > budget.maxEffects) {\n return this.failed(uiEffects, diagnostics, {\n kind: 'budget',\n message: `Form script transaction exceeded ${budget.maxEffects} effects`,\n });\n }\n if (effects.length === 0) {\n return { status: 'unchanged', scripted: true, effectsResult: null, uiEffects, diagnostics };\n }\n if (!this.options.doc.forms.applyEffects) {\n return this.failed(\n uiEffects,\n diagnostics,\n scriptError('This engine does not support batched form effects'),\n );\n }\n\n const effectsResult = await this.options.doc.forms.applyEffects(effects);\n const status = statusFromEffects(effectsResult);\n return {\n status,\n scripted: true,\n effectsResult,\n uiEffects,\n diagnostics,\n ...(status === 'failed'\n ? { error: scriptError('One or more native form effects failed') }\n : {}),\n };\n }\n\n private failed(\n uiEffects: FormUiEffect[],\n diagnostics: ScriptDiagnostic[],\n error: ScriptExecutionError,\n ): FormCommitResult {\n return {\n status: 'failed',\n scripted: true,\n effectsResult: null,\n uiEffects,\n diagnostics,\n error,\n };\n }\n\n private async finishRejected(\n bootEffects: FormEffect[],\n uiEffects: FormUiEffect[],\n diagnostics: ScriptDiagnostic[],\n ): Promise<FormCommitResult> {\n if (bootEffects.length === 0) {\n return {\n status: 'rejected',\n scripted: true,\n effectsResult: null,\n uiEffects,\n diagnostics,\n };\n }\n if (!this.options.doc.forms.applyEffects) {\n return this.failed(\n uiEffects,\n diagnostics,\n scriptError('Batched form effects are unavailable'),\n );\n }\n const effectsResult = await this.options.doc.forms.applyEffects(bootEffects);\n if (statusFromEffects(effectsResult) === 'failed') {\n return this.failed(uiEffects, diagnostics, scriptError('A name-tree boot effect failed'));\n }\n return {\n status: 'rejected',\n scripted: true,\n effectsResult,\n uiEffects,\n diagnostics,\n };\n }\n}\n\nexport function createFormScriptingController(\n options: FormScriptingControllerOptions,\n): FormScriptingController {\n return new FormScriptingController(options);\n}\n"],"mappings":"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"}
@@ -0,0 +1,47 @@
1
+ import { r as FormCommitResult } from "./types-CnUW7z1W.cjs";
2
+ import { DocumentMeta } from "@embedpdf/core";
3
+ import { DocumentHandle, FormFieldRef, FormFieldValue, PdfActionTree } from "@embedpdf/engine-core/runtime";
4
+ import { ScriptBudget, ScriptTransaction } from "@embedpdf/core-acrojs";
5
+ //#region src/scripting.d.ts
6
+ /**
7
+ * The controller never owns a realm. It rides a realm PORT — this document's
8
+ * own (the actions plugin's per-document host) or a detached one minted by
9
+ * the actions plugin for a document that is not displayed (stamp's
10
+ * asset documents). Either way the owner disposes the realm; `dispose()`
11
+ * here only fences further transactions.
12
+ */
13
+ interface FormScriptingControllerOptions {
14
+ doc: DocumentHandle;
15
+ document(): DocumentMeta | null;
16
+ /** The realm's transaction port ({@link ScriptTransaction}). The K/V/C/F
17
+ * pipeline runs WHOLLY inside one transaction: snapshot fetch, every
18
+ * pass, and the engine commit — the commit-inside-the-boundary law. */
19
+ transaction<T>(body: (txn: ScriptTransaction) => Promise<T>): Promise<T>;
20
+ /** The transaction aggregate (output bytes, wall-clock across passes);
21
+ * the realm owner hands over the same budget its runs enforce. */
22
+ budget?: ScriptBudget;
23
+ }
24
+ declare class FormScriptingController {
25
+ private readonly options;
26
+ private disposed;
27
+ private readonly transaction;
28
+ private readonly transactionBudget;
29
+ constructor(options: FormScriptingControllerOptions);
30
+ /** The realm belongs to its OWNER (the actions plugin, or the caller that
31
+ * minted a detached one) — this only fences further transactions. */
32
+ dispose(): void;
33
+ commit(ref: FormFieldRef, proposed: FormFieldValue): Promise<FormCommitResult>;
34
+ /** Execute one originating widget's activation action (`/A`, including `/Next`). */
35
+ activate(ref: FormFieldRef, action: PdfActionTree): Promise<FormCommitResult>;
36
+ /** Run lazy document boot plus the `/CO` chain without a user field change.
37
+ * The anchor field resolves INSIDE the transaction (undefined ref). */
38
+ recalculate(): Promise<FormCommitResult>;
39
+ private transact;
40
+ private transactBody;
41
+ private failed;
42
+ private finishRejected;
43
+ }
44
+ declare function createFormScriptingController(options: FormScriptingControllerOptions): FormScriptingController;
45
+ //#endregion
46
+ export { FormScriptingController, FormScriptingControllerOptions, createFormScriptingController };
47
+ //# sourceMappingURL=scripting.d.cts.map
@@ -0,0 +1,47 @@
1
+ import { r as FormCommitResult } from "./types-NGRZjJNj.js";
2
+ import { DocumentMeta } from "@embedpdf/core";
3
+ import { DocumentHandle, FormFieldRef, FormFieldValue, PdfActionTree } from "@embedpdf/engine-core/runtime";
4
+ import { ScriptBudget, ScriptTransaction } from "@embedpdf/core-acrojs";
5
+ //#region src/scripting.d.ts
6
+ /**
7
+ * The controller never owns a realm. It rides a realm PORT — this document's
8
+ * own (the actions plugin's per-document host) or a detached one minted by
9
+ * the actions plugin for a document that is not displayed (stamp's
10
+ * asset documents). Either way the owner disposes the realm; `dispose()`
11
+ * here only fences further transactions.
12
+ */
13
+ interface FormScriptingControllerOptions {
14
+ doc: DocumentHandle;
15
+ document(): DocumentMeta | null;
16
+ /** The realm's transaction port ({@link ScriptTransaction}). The K/V/C/F
17
+ * pipeline runs WHOLLY inside one transaction: snapshot fetch, every
18
+ * pass, and the engine commit — the commit-inside-the-boundary law. */
19
+ transaction<T>(body: (txn: ScriptTransaction) => Promise<T>): Promise<T>;
20
+ /** The transaction aggregate (output bytes, wall-clock across passes);
21
+ * the realm owner hands over the same budget its runs enforce. */
22
+ budget?: ScriptBudget;
23
+ }
24
+ declare class FormScriptingController {
25
+ private readonly options;
26
+ private disposed;
27
+ private readonly transaction;
28
+ private readonly transactionBudget;
29
+ constructor(options: FormScriptingControllerOptions);
30
+ /** The realm belongs to its OWNER (the actions plugin, or the caller that
31
+ * minted a detached one) — this only fences further transactions. */
32
+ dispose(): void;
33
+ commit(ref: FormFieldRef, proposed: FormFieldValue): Promise<FormCommitResult>;
34
+ /** Execute one originating widget's activation action (`/A`, including `/Next`). */
35
+ activate(ref: FormFieldRef, action: PdfActionTree): Promise<FormCommitResult>;
36
+ /** Run lazy document boot plus the `/CO` chain without a user field change.
37
+ * The anchor field resolves INSIDE the transaction (undefined ref). */
38
+ recalculate(): Promise<FormCommitResult>;
39
+ private transact;
40
+ private transactBody;
41
+ private failed;
42
+ private finishRejected;
43
+ }
44
+ declare function createFormScriptingController(options: FormScriptingControllerOptions): FormScriptingController;
45
+ //#endregion
46
+ export { FormScriptingController, FormScriptingControllerOptions, createFormScriptingController };
47
+ //# sourceMappingURL=scripting.d.ts.map