glost-processor 0.7.0 → 1.0.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.
@@ -0,0 +1,482 @@
1
+ /**
2
+ * GLOST Processor
3
+ *
4
+ * Unified-style processor for GLOST documents with fluent API.
5
+ * Similar to unified/remark processors.
6
+ *
7
+ * @packageDocumentation
8
+ */
9
+ import { processGLOSTWithExtensionsAsync, extensionRegistry } from "glost-extensions";
10
+ /**
11
+ * GLOST Processor
12
+ *
13
+ * Fluent API for processing GLOST documents through plugin pipelines.
14
+ *
15
+ * @example
16
+ * ```typescript
17
+ * import { GLOSTProcessor } from "glost-processor";
18
+ *
19
+ * const processor = new GLOSTProcessor()
20
+ * .use(transcription, { scheme: "ipa" })
21
+ * .use(translation, { target: "en" })
22
+ * .use(frequency);
23
+ *
24
+ * const result = await processor.process(document);
25
+ * ```
26
+ */
27
+ export class GLOSTProcessor {
28
+ plugins = [];
29
+ hooks = {
30
+ before: new Map(),
31
+ after: new Map(),
32
+ onError: [],
33
+ onSkip: [],
34
+ onProgress: [],
35
+ };
36
+ dataStore = new Map();
37
+ options = {};
38
+ frozen = false;
39
+ /**
40
+ * Create a new processor instance
41
+ *
42
+ * @param options - Initial processor options
43
+ */
44
+ constructor(options = {}) {
45
+ this.options = { ...options };
46
+ if (options.data) {
47
+ this.dataStore = new Map(options.data);
48
+ }
49
+ }
50
+ /**
51
+ * Use a plugin, preset, or extension
52
+ *
53
+ * @param spec - Plugin function, extension object, preset, or plugin ID
54
+ * @param options - Plugin options
55
+ * @returns This processor for chaining
56
+ *
57
+ * @example
58
+ * ```typescript
59
+ * processor
60
+ * .use(transcription, { scheme: "ipa" })
61
+ * .use(translation)
62
+ * .use("frequency");
63
+ * ```
64
+ */
65
+ use(spec, options) {
66
+ this.assertNotFrozen();
67
+ // Handle presets
68
+ if (this.isPreset(spec)) {
69
+ return this.usePreset(spec);
70
+ }
71
+ // Add plugin to pipeline
72
+ this.plugins.push({ spec, options });
73
+ return this;
74
+ }
75
+ /**
76
+ * Apply a preset (collection of plugins)
77
+ *
78
+ * @param preset - Preset to apply
79
+ * @returns This processor for chaining
80
+ */
81
+ usePreset(preset) {
82
+ for (const pluginEntry of preset.plugins) {
83
+ if (Array.isArray(pluginEntry)) {
84
+ const [plugin, opts] = pluginEntry;
85
+ this.use(plugin, opts);
86
+ }
87
+ else {
88
+ this.use(pluginEntry);
89
+ }
90
+ }
91
+ return this;
92
+ }
93
+ /**
94
+ * Register a hook to run before a plugin
95
+ *
96
+ * @param pluginId - Plugin ID to hook into
97
+ * @param hook - Hook function to run
98
+ * @returns This processor for chaining
99
+ *
100
+ * @example
101
+ * ```typescript
102
+ * processor.before("translation", (doc) => {
103
+ * console.log("About to translate");
104
+ * });
105
+ * ```
106
+ */
107
+ before(pluginId, hook) {
108
+ this.assertNotFrozen();
109
+ if (!this.hooks.before.has(pluginId)) {
110
+ this.hooks.before.set(pluginId, []);
111
+ }
112
+ this.hooks.before.get(pluginId).push(hook);
113
+ return this;
114
+ }
115
+ /**
116
+ * Register a hook to run after a plugin
117
+ *
118
+ * @param pluginId - Plugin ID to hook into
119
+ * @param hook - Hook function to run
120
+ * @returns This processor for chaining
121
+ *
122
+ * @example
123
+ * ```typescript
124
+ * processor.after("translation", (doc) => {
125
+ * console.log("Translation complete");
126
+ * });
127
+ * ```
128
+ */
129
+ after(pluginId, hook) {
130
+ this.assertNotFrozen();
131
+ if (!this.hooks.after.has(pluginId)) {
132
+ this.hooks.after.set(pluginId, []);
133
+ }
134
+ this.hooks.after.get(pluginId).push(hook);
135
+ return this;
136
+ }
137
+ /**
138
+ * Register an error handler
139
+ *
140
+ * @param hook - Error handler function
141
+ * @returns This processor for chaining
142
+ *
143
+ * @example
144
+ * ```typescript
145
+ * processor.onError((error, plugin) => {
146
+ * console.error(`Plugin ${plugin} failed:`, error);
147
+ * });
148
+ * ```
149
+ */
150
+ onError(hook) {
151
+ this.assertNotFrozen();
152
+ this.hooks.onError.push(hook);
153
+ return this;
154
+ }
155
+ /**
156
+ * Register a skip handler
157
+ *
158
+ * @param hook - Skip handler function
159
+ * @returns This processor for chaining
160
+ *
161
+ * @example
162
+ * ```typescript
163
+ * processor.onSkip((plugin, reason) => {
164
+ * console.log(`Plugin ${plugin} skipped: ${reason}`);
165
+ * });
166
+ * ```
167
+ */
168
+ onSkip(hook) {
169
+ this.assertNotFrozen();
170
+ this.hooks.onSkip.push(hook);
171
+ return this;
172
+ }
173
+ /**
174
+ * Register a progress handler
175
+ *
176
+ * @param hook - Progress handler function
177
+ * @returns This processor for chaining
178
+ *
179
+ * @example
180
+ * ```typescript
181
+ * processor.onProgress((stats) => {
182
+ * console.log(`Progress: ${stats.completed}/${stats.total}`);
183
+ * });
184
+ * ```
185
+ */
186
+ onProgress(hook) {
187
+ this.assertNotFrozen();
188
+ this.hooks.onProgress.push(hook);
189
+ return this;
190
+ }
191
+ data(key, value) {
192
+ if (arguments.length === 1) {
193
+ return this.dataStore.get(key);
194
+ }
195
+ this.assertNotFrozen();
196
+ this.dataStore.set(key, value);
197
+ return this;
198
+ }
199
+ /**
200
+ * Freeze the processor
201
+ *
202
+ * Returns a frozen processor that cannot be modified.
203
+ * Useful for reusing the same configuration across multiple documents.
204
+ *
205
+ * @returns A frozen copy of this processor
206
+ *
207
+ * @example
208
+ * ```typescript
209
+ * const frozen = processor
210
+ * .use(transcription)
211
+ * .use(translation)
212
+ * .freeze();
213
+ *
214
+ * // Can process multiple documents with the same pipeline
215
+ * const result1 = await frozen.process(doc1);
216
+ * const result2 = await frozen.process(doc2);
217
+ * ```
218
+ */
219
+ freeze() {
220
+ const frozen = new GLOSTProcessor(this.options);
221
+ frozen.plugins = [...this.plugins];
222
+ frozen.hooks = {
223
+ before: new Map(this.hooks.before),
224
+ after: new Map(this.hooks.after),
225
+ onError: [...this.hooks.onError],
226
+ onSkip: [...this.hooks.onSkip],
227
+ onProgress: [...this.hooks.onProgress],
228
+ };
229
+ frozen.dataStore = new Map(this.dataStore);
230
+ frozen.frozen = true;
231
+ return frozen;
232
+ }
233
+ /**
234
+ * Process a document through the pipeline
235
+ *
236
+ * @param document - GLOST document to process
237
+ * @returns Promise resolving to the processed document
238
+ *
239
+ * @example
240
+ * ```typescript
241
+ * const result = await processor.process(document);
242
+ * console.log(result);
243
+ * ```
244
+ */
245
+ async process(document) {
246
+ const result = await this.processWithMeta(document);
247
+ return result.document;
248
+ }
249
+ /**
250
+ * Process a document and return detailed metadata
251
+ *
252
+ * @param document - GLOST document to process
253
+ * @returns Promise resolving to processing result with metadata
254
+ *
255
+ * @example
256
+ * ```typescript
257
+ * const result = await processor.processWithMeta(document);
258
+ * console.log(result.metadata.appliedPlugins);
259
+ * console.log(result.metadata.stats.totalTime);
260
+ * ```
261
+ */
262
+ async processWithMeta(document) {
263
+ const startTime = Date.now();
264
+ const extensions = await this.resolveExtensions();
265
+ const timing = new Map();
266
+ const errors = [];
267
+ const warnings = [];
268
+ const appliedPlugins = [];
269
+ const skippedPlugins = [];
270
+ // Emit initial progress
271
+ this.emitProgress({
272
+ total: extensions.length,
273
+ completed: 0,
274
+ startTime,
275
+ elapsed: 0,
276
+ });
277
+ // Process extensions with hooks
278
+ let processedDoc = document;
279
+ for (let i = 0; i < extensions.length; i++) {
280
+ const extension = extensions[i];
281
+ const pluginStart = Date.now();
282
+ try {
283
+ // Run before hooks
284
+ await this.runBeforeHooks(processedDoc, extension.id);
285
+ // Process with this extension
286
+ const { data: _, ...extensionOptions } = this.options;
287
+ const result = await processGLOSTWithExtensionsAsync(processedDoc, [extension], extensionOptions);
288
+ processedDoc = result.document;
289
+ // Check for errors/skips
290
+ if (result.metadata.errors.length > 0) {
291
+ for (const err of result.metadata.errors) {
292
+ errors.push({
293
+ plugin: extension.id,
294
+ phase: "transform",
295
+ message: err.error.message,
296
+ stack: err.error.stack,
297
+ recoverable: true,
298
+ error: err.error,
299
+ });
300
+ }
301
+ }
302
+ if (result.metadata.skippedExtensions.includes(extension.id)) {
303
+ skippedPlugins.push(extension.id);
304
+ this.emitSkip(extension.id, "Skipped by processor");
305
+ }
306
+ else {
307
+ appliedPlugins.push(extension.id);
308
+ }
309
+ // Run after hooks
310
+ await this.runAfterHooks(processedDoc, extension.id);
311
+ // Record timing
312
+ timing.set(extension.id, Date.now() - pluginStart);
313
+ // Emit progress
314
+ this.emitProgress({
315
+ total: extensions.length,
316
+ completed: i + 1,
317
+ current: extension.id,
318
+ startTime,
319
+ elapsed: Date.now() - startTime,
320
+ });
321
+ }
322
+ catch (error) {
323
+ const err = error instanceof Error ? error : new Error(String(error));
324
+ errors.push({
325
+ plugin: extension.id,
326
+ phase: "transform",
327
+ message: err.message,
328
+ stack: err.stack,
329
+ recoverable: false,
330
+ error: err,
331
+ });
332
+ skippedPlugins.push(extension.id);
333
+ this.emitError(err, extension.id);
334
+ this.emitSkip(extension.id, err.message);
335
+ // Re-throw in strict mode
336
+ if (!this.options.lenient) {
337
+ throw err;
338
+ }
339
+ }
340
+ }
341
+ const endTime = Date.now();
342
+ return {
343
+ document: processedDoc,
344
+ metadata: {
345
+ appliedPlugins,
346
+ skippedPlugins,
347
+ errors,
348
+ warnings,
349
+ stats: {
350
+ totalTime: endTime - startTime,
351
+ timing,
352
+ nodesProcessed: 0, // Could be calculated by visiting the tree
353
+ startTime,
354
+ endTime,
355
+ },
356
+ },
357
+ };
358
+ }
359
+ /**
360
+ * Process a document synchronously (only if all plugins are sync)
361
+ *
362
+ * @param document - GLOST document to process
363
+ * @returns The processed document
364
+ * @throws {Error} If any plugin is async
365
+ *
366
+ * @example
367
+ * ```typescript
368
+ * const result = processor.processSync(document);
369
+ * ```
370
+ */
371
+ processSync(document) {
372
+ throw new Error("Synchronous processing not yet implemented. Use process() instead.");
373
+ }
374
+ /**
375
+ * Resolve all plugins to extensions
376
+ */
377
+ async resolveExtensions() {
378
+ const extensions = [];
379
+ for (const { spec, options } of this.plugins) {
380
+ const extension = await this.resolvePlugin(spec, options);
381
+ if (extension) {
382
+ extensions.push(extension);
383
+ }
384
+ }
385
+ return extensions;
386
+ }
387
+ /**
388
+ * Resolve a single plugin to an extension
389
+ */
390
+ async resolvePlugin(spec, options) {
391
+ // String ID - lookup in registry
392
+ if (typeof spec === "string") {
393
+ const ext = extensionRegistry.get(spec);
394
+ if (!ext) {
395
+ throw new Error(`Plugin "${spec}" not found in registry`);
396
+ }
397
+ return ext;
398
+ }
399
+ // Function - call to get extension
400
+ if (typeof spec === "function") {
401
+ const result = spec(options);
402
+ return result || null;
403
+ }
404
+ // Extension object - use directly
405
+ return spec;
406
+ }
407
+ /**
408
+ * Check if a spec is a preset
409
+ */
410
+ isPreset(spec) {
411
+ return (spec &&
412
+ typeof spec === "object" &&
413
+ "plugins" in spec &&
414
+ Array.isArray(spec.plugins));
415
+ }
416
+ /**
417
+ * Run before hooks for a plugin
418
+ */
419
+ async runBeforeHooks(document, pluginId) {
420
+ const hooks = this.hooks.before.get(pluginId) || [];
421
+ for (const hook of hooks) {
422
+ await hook(document, pluginId);
423
+ }
424
+ }
425
+ /**
426
+ * Run after hooks for a plugin
427
+ */
428
+ async runAfterHooks(document, pluginId) {
429
+ const hooks = this.hooks.after.get(pluginId) || [];
430
+ for (const hook of hooks) {
431
+ await hook(document, pluginId);
432
+ }
433
+ }
434
+ /**
435
+ * Emit error to error handlers
436
+ */
437
+ emitError(error, pluginId) {
438
+ for (const hook of this.hooks.onError) {
439
+ try {
440
+ hook(error, pluginId);
441
+ }
442
+ catch (err) {
443
+ console.error("Error in error hook:", err);
444
+ }
445
+ }
446
+ }
447
+ /**
448
+ * Emit skip to skip handlers
449
+ */
450
+ emitSkip(pluginId, reason) {
451
+ for (const hook of this.hooks.onSkip) {
452
+ try {
453
+ hook(pluginId, reason);
454
+ }
455
+ catch (err) {
456
+ console.error("Error in skip hook:", err);
457
+ }
458
+ }
459
+ }
460
+ /**
461
+ * Emit progress to progress handlers
462
+ */
463
+ emitProgress(stats) {
464
+ for (const hook of this.hooks.onProgress) {
465
+ try {
466
+ hook(stats);
467
+ }
468
+ catch (err) {
469
+ console.error("Error in progress hook:", err);
470
+ }
471
+ }
472
+ }
473
+ /**
474
+ * Assert that the processor is not frozen
475
+ */
476
+ assertNotFrozen() {
477
+ if (this.frozen) {
478
+ throw new Error("Cannot modify frozen processor");
479
+ }
480
+ }
481
+ }
482
+ //# sourceMappingURL=processor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"processor.js","sourceRoot":"","sources":["processor.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,145 @@
1
+ /**
2
+ * GLOST Stream Processor
3
+ *
4
+ * Streaming variant of GLOSTProcessor that yields processed sentence
5
+ * batches progressively using AsyncGenerator. Keeps the full document
6
+ * out of memory between chunks.
7
+ *
8
+ * Document-level transforms (extensions with streamingSupport !== 'chunk')
9
+ * run once on the full document before streaming begins. Chunk-compatible
10
+ * extensions (streamingSupport === 'chunk') then run on each batch.
11
+ *
12
+ * @packageDocumentation
13
+ *
14
+ * @example
15
+ * ```typescript
16
+ * import { GLOSTStreamProcessor } from "glost-processor";
17
+ *
18
+ * const processor = new GLOSTStreamProcessor()
19
+ * .use(transcription)
20
+ * .use(translation);
21
+ *
22
+ * for await (const chunk of processor.stream(document)) {
23
+ * console.log(chunk.sentences, chunk.isLast);
24
+ * }
25
+ * ```
26
+ *
27
+ * @since 0.7.0
28
+ */
29
+ import type { GLOSTRoot, GLOSTSentence } from "glost-core";
30
+ import type { PluginSpec, Preset, ProcessorOptions } from "./types.js";
31
+ /**
32
+ * Options for stream() method
33
+ *
34
+ * @since 0.7.0
35
+ */
36
+ export interface StreamOptions {
37
+ /**
38
+ * Number of sentences per chunk.
39
+ *
40
+ * A smaller value reduces latency to first yielded chunk; a larger
41
+ * value amortises per-chunk overhead. Default: 50.
42
+ */
43
+ batchSize?: number;
44
+ }
45
+ /**
46
+ * A single yielded chunk from the stream
47
+ *
48
+ * @since 0.7.0
49
+ */
50
+ export interface ProcessedChunk {
51
+ /** Processed sentences in this batch */
52
+ sentences: GLOSTSentence[];
53
+ /**
54
+ * Index of the source paragraph this chunk came from.
55
+ *
56
+ * When the document has multiple paragraphs each paragraph is
57
+ * chunked independently, so multiple consecutive chunks may share
58
+ * the same paragraphIndex.
59
+ */
60
+ paragraphIndex: number;
61
+ /**
62
+ * Index of this chunk within its paragraph (0-based).
63
+ */
64
+ chunkIndex: number;
65
+ /** True for the final chunk across the whole document */
66
+ isLast: boolean;
67
+ }
68
+ /**
69
+ * Streaming processor for GLOST documents
70
+ *
71
+ * Mirrors the `GLOSTProcessor` API (`.use()`, `.freeze()`) but adds a
72
+ * `.stream()` method that returns an `AsyncGenerator<ProcessedChunk>`.
73
+ *
74
+ * @since 0.7.0
75
+ */
76
+ export declare class GLOSTStreamProcessor {
77
+ private plugins;
78
+ private options;
79
+ private frozen;
80
+ /**
81
+ * Create a new stream processor instance
82
+ *
83
+ * @param options - Initial processor options
84
+ */
85
+ constructor(options?: ProcessorOptions);
86
+ /**
87
+ * Add a plugin, preset, or extension to the pipeline
88
+ *
89
+ * @param spec - Plugin function, extension object, preset, or ID
90
+ * @param options - Plugin options
91
+ * @returns This processor for chaining
92
+ */
93
+ use(spec: PluginSpec | Preset, options?: unknown): this;
94
+ /**
95
+ * Freeze the processor
96
+ *
97
+ * Returns a frozen processor that cannot be modified. Useful for
98
+ * reusing the same pipeline configuration across multiple documents.
99
+ *
100
+ * @returns A frozen copy of this processor
101
+ */
102
+ freeze(): FrozenStreamProcessor;
103
+ /**
104
+ * Stream a document as progressive sentence batches
105
+ *
106
+ * Processing phases:
107
+ * 1. All extensions with `streamingSupport !== 'chunk'` (i.e. `'none'`
108
+ * or `'full'`, or unset) run their `transform`, `visit`, and
109
+ * `enhanceMetadata` hooks on the **full** document.
110
+ * 2. The resulting document is split into sentence batches.
111
+ * 3. For each batch, extensions with `streamingSupport === 'chunk'`
112
+ * run their `visit` and `enhanceMetadata` hooks.
113
+ * 4. A `ProcessedChunk` is yielded.
114
+ *
115
+ * Cancellation: break out of the `for await` loop at any time. The
116
+ * generator will stop without processing remaining chunks.
117
+ *
118
+ * @param document - GLOST document to stream
119
+ * @param streamOptions - Streaming options (batchSize etc.)
120
+ * @yields `ProcessedChunk` objects in document order
121
+ *
122
+ * @example
123
+ * ```typescript
124
+ * for await (const chunk of processor.stream(doc, { batchSize: 20 })) {
125
+ * console.log(`para ${chunk.paragraphIndex} chunk ${chunk.chunkIndex}`);
126
+ * if (chunk.isLast) console.log("done");
127
+ * }
128
+ * ```
129
+ */
130
+ stream(document: GLOSTRoot, streamOptions?: StreamOptions): AsyncGenerator<ProcessedChunk>;
131
+ private usePreset;
132
+ private resolveExtensions;
133
+ private resolvePlugin;
134
+ private isPreset;
135
+ private assertNotFrozen;
136
+ }
137
+ /**
138
+ * A frozen `GLOSTStreamProcessor` that cannot be modified.
139
+ *
140
+ * @since 0.7.0
141
+ */
142
+ export type FrozenStreamProcessor = Omit<GLOSTStreamProcessor, "use" | "freeze"> & {
143
+ readonly frozen: true;
144
+ };
145
+ //# sourceMappingURL=stream-processor.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stream-processor.d.ts","sourceRoot":"","sources":["stream-processor.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAO3D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAMvE;;;;GAIG;AACH,MAAM,WAAW,aAAa;IAC5B;;;;;OAKG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED;;;;GAIG;AACH,MAAM,WAAW,cAAc;IAC7B,wCAAwC;IACxC,SAAS,EAAE,aAAa,EAAE,CAAC;IAE3B;;;;;;OAMG;IACH,cAAc,EAAE,MAAM,CAAC;IAEvB;;OAEG;IACH,UAAU,EAAE,MAAM,CAAC;IAEnB,yDAAyD;IACzD,MAAM,EAAE,OAAO,CAAC;CACjB;AAMD;;;;;;;GAOG;AACH,qBAAa,oBAAoB;IAC/B,OAAO,CAAC,OAAO,CAAsD;IACrE,OAAO,CAAC,OAAO,CAAwB;IACvC,OAAO,CAAC,MAAM,CAAS;IAEvB;;;;OAIG;gBACS,OAAO,GAAE,gBAAqB;IAI1C;;;;;;OAMG;IACH,GAAG,CAAC,IAAI,EAAE,UAAU,GAAG,MAAM,EAAE,OAAO,CAAC,EAAE,OAAO,GAAG,IAAI;IAWvD;;;;;;;OAOG;IACH,MAAM,IAAI,qBAAqB;IAO/B;;;;;;;;;;;;;;;;;;;;;;;;;;OA0BG;IACI,MAAM,CACX,QAAQ,EAAE,SAAS,EACnB,aAAa,CAAC,EAAE,aAAa,GAC5B,cAAc,CAAC,cAAc,CAAC;IAiGjC,OAAO,CAAC,SAAS;YAYH,iBAAiB;YAWjB,aAAa;IAsB3B,OAAO,CAAC,QAAQ;IAShB,OAAO,CAAC,eAAe;CAKxB;AAMD;;;;GAIG;AACH,MAAM,MAAM,qBAAqB,GAAG,IAAI,CACtC,oBAAoB,EACpB,KAAK,GAAG,QAAQ,CACjB,GAAG;IAAE,QAAQ,CAAC,MAAM,EAAE,IAAI,CAAA;CAAE,CAAC"}