wiki-graph-core 0.3.1
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 +201 -0
- package/data/editor/clue_reviewer.jinja +410 -0
- package/data/editor/clue_reviewer_generator.jinja +428 -0
- package/data/editor/revision_feedback.jinja +5 -0
- package/data/editor/text_compressor.jinja +127 -0
- package/data/guaranteed/response_intent_classifier.jinja +8 -0
- package/data/help/commands/archive/next.jinja +29 -0
- package/data/help/commands/gc.jinja +38 -0
- package/data/help/commands/legacy/migrate.jinja +20 -0
- package/data/help/commands/legacy.jinja +19 -0
- package/data/help/commands/maintenance/chapter/add.jinja +41 -0
- package/data/help/commands/maintenance/chapter/list.jinja +33 -0
- package/data/help/commands/maintenance/chapter/move.jinja +36 -0
- package/data/help/commands/maintenance/chapter/remove.jinja +26 -0
- package/data/help/commands/maintenance/chapter/reset.jinja +29 -0
- package/data/help/commands/maintenance/chapter/set-source.jinja +34 -0
- package/data/help/commands/maintenance/chapter/set-summary.jinja +31 -0
- package/data/help/commands/maintenance/chapter/set-title.jinja +29 -0
- package/data/help/commands/maintenance/chapter/tree.jinja +58 -0
- package/data/help/commands/maintenance/chapter.jinja +59 -0
- package/data/help/commands/maintenance/cover.jinja +28 -0
- package/data/help/commands/maintenance/meta.jinja +55 -0
- package/data/help/commands/predicate.jinja +460 -0
- package/data/help/commands/root.jinja +83 -0
- package/data/help/commands/transform.jinja +34 -0
- package/data/help/commands/uri.jinja +274 -0
- package/data/help/topics/config.jinja +88 -0
- package/data/help/topics/format.jinja +72 -0
- package/data/help/topics/readiness.jinja +99 -0
- package/data/help/topics/recipe.jinja +151 -0
- package/data/help/topics/runtime.jinja +62 -0
- package/data/help/topics/uri.jinja +178 -0
- package/data/output/epub/cover.xhtml.jinja +13 -0
- package/data/output/epub/nav.xhtml.jinja +12 -0
- package/data/output/epub/package.opf.xml.jinja +39 -0
- package/data/output/epub/section.xhtml.jinja +12 -0
- package/data/topologization/book_coherence_extraction.jinja +223 -0
- package/data/topologization/chunk_extraction.jinja +233 -0
- package/data/topologization/evidence_choice.jinja +38 -0
- package/data/topologization/translate_chunks.jinja +138 -0
- package/data/topologization/user_focused_extraction.jinja +378 -0
- package/dist/archive/query/archive-view.d.ts +26 -0
- package/dist/archive/query/archive-view.js +4540 -0
- package/dist/archive/query/archive-view.js.map +1 -0
- package/dist/archive/query/continuation-cursor.d.ts +61 -0
- package/dist/archive/query/continuation-cursor.js +363 -0
- package/dist/archive/query/continuation-cursor.js.map +1 -0
- package/dist/archive/query/index.d.ts +29 -0
- package/dist/archive/query/index.js +63 -0
- package/dist/archive/query/index.js.map +1 -0
- package/dist/archive/query/lexical-search.d.ts +22 -0
- package/dist/archive/query/lexical-search.js +137 -0
- package/dist/archive/query/lexical-search.js.map +1 -0
- package/dist/archive/query/search-cache.d.ts +192 -0
- package/dist/archive/query/search-cache.js +1248 -0
- package/dist/archive/query/search-cache.js.map +1 -0
- package/dist/archive/search-index/index.d.ts +26 -0
- package/dist/archive/search-index/index.js +29 -0
- package/dist/archive/search-index/index.js.map +1 -0
- package/dist/archive/search-index/search-index.d.ts +26 -0
- package/dist/archive/search-index/search-index.js +555 -0
- package/dist/archive/search-index/search-index.js.map +1 -0
- package/dist/archive/search-index/search-tokenizer.d.ts +16 -0
- package/dist/archive/search-index/search-tokenizer.js +225 -0
- package/dist/archive/search-index/search-tokenizer.js.map +1 -0
- package/dist/common/cli-command.d.ts +4 -0
- package/dist/common/cli-command.js +7 -0
- package/dist/common/cli-command.js.map +1 -0
- package/dist/common/data-dir.d.ts +3 -0
- package/dist/common/data-dir.js +48 -0
- package/dist/common/data-dir.js.map +1 -0
- package/dist/common/language.d.ts +55 -0
- package/dist/common/language.js +208 -0
- package/dist/common/language.js.map +1 -0
- package/dist/common/llm-scope.d.ts +19 -0
- package/dist/common/llm-scope.js +31 -0
- package/dist/common/llm-scope.js.map +1 -0
- package/dist/common/logging.d.ts +22 -0
- package/dist/common/logging.js +141 -0
- package/dist/common/logging.js.map +1 -0
- package/dist/common/template.d.ts +8 -0
- package/dist/common/template.js +54 -0
- package/dist/common/template.js.map +1 -0
- package/dist/common/tinyld-language.d.ts +6 -0
- package/dist/common/tinyld-language.js +34 -0
- package/dist/common/tinyld-language.js.map +1 -0
- package/dist/common/wiki-graph-dir.d.ts +10 -0
- package/dist/common/wiki-graph-dir.js +41 -0
- package/dist/common/wiki-graph-dir.js.map +1 -0
- package/dist/common/wiki-graph-temp.d.ts +6 -0
- package/dist/common/wiki-graph-temp.js +21 -0
- package/dist/common/wiki-graph-temp.js.map +1 -0
- package/dist/common/wiki-graph-uri.d.ts +28 -0
- package/dist/common/wiki-graph-uri.js +171 -0
- package/dist/common/wiki-graph-uri.js.map +1 -0
- package/dist/context/index.d.ts +1 -0
- package/dist/context/index.js +13 -0
- package/dist/context/index.js.map +1 -0
- package/dist/context/task-context.d.ts +41 -0
- package/dist/context/task-context.js +111 -0
- package/dist/context/task-context.js.map +1 -0
- package/dist/document/database.d.ts +30 -0
- package/dist/document/database.js +273 -0
- package/dist/document/database.js.map +1 -0
- package/dist/document/document.d.ts +153 -0
- package/dist/document/document.js +615 -0
- package/dist/document/document.js.map +1 -0
- package/dist/document/fragments.d.ts +63 -0
- package/dist/document/fragments.js +371 -0
- package/dist/document/fragments.js.map +1 -0
- package/dist/document/index.d.ts +13 -0
- package/dist/document/index.js +62 -0
- package/dist/document/index.js.map +1 -0
- package/dist/document/schema.d.ts +8 -0
- package/dist/document/schema.js +472 -0
- package/dist/document/schema.js.map +1 -0
- package/dist/document/shared-state-database.d.ts +9 -0
- package/dist/document/shared-state-database.js +193 -0
- package/dist/document/shared-state-database.js.map +1 -0
- package/dist/document/stores.d.ts +203 -0
- package/dist/document/stores.js +1678 -0
- package/dist/document/stores.js.map +1 -0
- package/dist/document/text-streams.d.ts +86 -0
- package/dist/document/text-streams.js +515 -0
- package/dist/document/text-streams.js.map +1 -0
- package/dist/document/types.d.ts +148 -0
- package/dist/document/types.js +69 -0
- package/dist/document/types.js.map +1 -0
- package/dist/editor/clue.d.ts +27 -0
- package/dist/editor/clue.js +158 -0
- package/dist/editor/clue.js.map +1 -0
- package/dist/editor/compressor.d.ts +18 -0
- package/dist/editor/compressor.js +68 -0
- package/dist/editor/compressor.js.map +1 -0
- package/dist/editor/editor.d.ts +39 -0
- package/dist/editor/editor.js +253 -0
- package/dist/editor/editor.js.map +1 -0
- package/dist/editor/feedback.d.ts +16 -0
- package/dist/editor/feedback.js +104 -0
- package/dist/editor/feedback.js.map +1 -0
- package/dist/editor/index.d.ts +17 -0
- package/dist/editor/index.js +5 -0
- package/dist/editor/index.js.map +1 -0
- package/dist/editor/language-review.d.ts +14 -0
- package/dist/editor/language-review.js +35 -0
- package/dist/editor/language-review.js.map +1 -0
- package/dist/editor/log.d.ts +37 -0
- package/dist/editor/log.js +202 -0
- package/dist/editor/log.js.map +1 -0
- package/dist/editor/markup.d.ts +20 -0
- package/dist/editor/markup.js +294 -0
- package/dist/editor/markup.js.map +1 -0
- package/dist/editor/prompt-templates.d.ts +6 -0
- package/dist/editor/prompt-templates.js +11 -0
- package/dist/editor/prompt-templates.js.map +1 -0
- package/dist/editor/response.d.ts +5 -0
- package/dist/editor/response.js +31 -0
- package/dist/editor/response.js.map +1 -0
- package/dist/editor/review.d.ts +34 -0
- package/dist/editor/review.js +189 -0
- package/dist/editor/review.js.map +1 -0
- package/dist/editor/types.d.ts +31 -0
- package/dist/editor/types.js +21 -0
- package/dist/editor/types.js.map +1 -0
- package/dist/evidence-selection/anchor-resolver.d.ts +43 -0
- package/dist/evidence-selection/anchor-resolver.js +783 -0
- package/dist/evidence-selection/anchor-resolver.js.map +1 -0
- package/dist/evidence-selection/anchor-types.d.ts +27 -0
- package/dist/evidence-selection/anchor-types.js +1 -0
- package/dist/evidence-selection/anchor-types.js.map +1 -0
- package/dist/evidence-selection/index.d.ts +8 -0
- package/dist/evidence-selection/index.js +32 -0
- package/dist/evidence-selection/index.js.map +1 -0
- package/dist/evidence-selection/prompt.d.ts +18 -0
- package/dist/evidence-selection/prompt.js +54 -0
- package/dist/evidence-selection/prompt.js.map +1 -0
- package/dist/evidence-selection/quote-score.d.ts +29 -0
- package/dist/evidence-selection/quote-score.js +331 -0
- package/dist/evidence-selection/quote-score.js.map +1 -0
- package/dist/evidence-selection/selection-resolver.d.ts +19 -0
- package/dist/evidence-selection/selection-resolver.js +303 -0
- package/dist/evidence-selection/selection-resolver.js.map +1 -0
- package/dist/evidence-selection/text.d.ts +4 -0
- package/dist/evidence-selection/text.js +66 -0
- package/dist/evidence-selection/text.js.map +1 -0
- package/dist/evidence-selection/types.d.ts +36 -0
- package/dist/evidence-selection/types.js +1 -0
- package/dist/evidence-selection/types.js.map +1 -0
- package/dist/facade/app.d.ts +75 -0
- package/dist/facade/app.js +141 -0
- package/dist/facade/app.js.map +1 -0
- package/dist/facade/build-queue.d.ts +181 -0
- package/dist/facade/build-queue.js +1442 -0
- package/dist/facade/build-queue.js.map +1 -0
- package/dist/facade/chapter-build.d.ts +60 -0
- package/dist/facade/chapter-build.js +1020 -0
- package/dist/facade/chapter-build.js.map +1 -0
- package/dist/facade/chapter.d.ts +168 -0
- package/dist/facade/chapter.js +944 -0
- package/dist/facade/chapter.js.map +1 -0
- package/dist/facade/digest.d.ts +55 -0
- package/dist/facade/digest.js +168 -0
- package/dist/facade/digest.js.map +1 -0
- package/dist/facade/graph.d.ts +60 -0
- package/dist/facade/graph.js +203 -0
- package/dist/facade/graph.js.map +1 -0
- package/dist/facade/import.d.ts +49 -0
- package/dist/facade/import.js +262 -0
- package/dist/facade/import.js.map +1 -0
- package/dist/facade/index.d.ts +39 -0
- package/dist/facade/index.js +171 -0
- package/dist/facade/index.js.map +1 -0
- package/dist/facade/knowledge-graph-build.d.ts +75 -0
- package/dist/facade/knowledge-graph-build.js +897 -0
- package/dist/facade/knowledge-graph-build.js.map +1 -0
- package/dist/facade/llm-sampling.d.ts +11 -0
- package/dist/facade/llm-sampling.js +58 -0
- package/dist/facade/llm-sampling.js.map +1 -0
- package/dist/facade/types.d.ts +8 -0
- package/dist/facade/types.js +1 -0
- package/dist/facade/types.js.map +1 -0
- package/dist/facade/wiki-graph-archive.d.ts +41 -0
- package/dist/facade/wiki-graph-archive.js +130 -0
- package/dist/facade/wiki-graph-archive.js.map +1 -0
- package/dist/gc/files.d.ts +15 -0
- package/dist/gc/files.js +141 -0
- package/dist/gc/files.js.map +1 -0
- package/dist/gc/index.d.ts +2 -0
- package/dist/gc/index.js +5 -0
- package/dist/gc/index.js.map +1 -0
- package/dist/gc/lock.d.ts +3 -0
- package/dist/gc/lock.js +137 -0
- package/dist/gc/lock.js.map +1 -0
- package/dist/gc/runner.d.ts +9 -0
- package/dist/gc/runner.js +129 -0
- package/dist/gc/runner.js.map +1 -0
- package/dist/gc/tmp-gc.d.ts +5 -0
- package/dist/gc/tmp-gc.js +57 -0
- package/dist/gc/tmp-gc.js.map +1 -0
- package/dist/gc/types.d.ts +24 -0
- package/dist/gc/types.js +1 -0
- package/dist/gc/types.js.map +1 -0
- package/dist/gc.cjs +10041 -0
- package/dist/gc.cjs.map +1 -0
- package/dist/gc.d.cts +10 -0
- package/dist/gc.d.ts +2 -0
- package/dist/gc.js +5 -0
- package/dist/gc.js.map +1 -0
- package/dist/guaranteed/classifier.d.ts +10 -0
- package/dist/guaranteed/classifier.js +88 -0
- package/dist/guaranteed/classifier.js.map +1 -0
- package/dist/guaranteed/errors.d.ts +38 -0
- package/dist/guaranteed/errors.js +73 -0
- package/dist/guaranteed/errors.js.map +1 -0
- package/dist/guaranteed/index.d.ts +7 -0
- package/dist/guaranteed/index.js +21 -0
- package/dist/guaranteed/index.js.map +1 -0
- package/dist/guaranteed/request.d.ts +8 -0
- package/dist/guaranteed/request.js +206 -0
- package/dist/guaranteed/request.js.map +1 -0
- package/dist/guaranteed/response.d.ts +12 -0
- package/dist/guaranteed/response.js +98 -0
- package/dist/guaranteed/response.js.map +1 -0
- package/dist/guaranteed/types.d.ts +20 -0
- package/dist/guaranteed/types.js +1 -0
- package/dist/guaranteed/types.js.map +1 -0
- package/dist/index-B8NNnQ8P.d.ts +424 -0
- package/dist/index.cjs +34774 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +2462 -0
- package/dist/index.d.ts +79 -0
- package/dist/index.js +168 -0
- package/dist/index.js.map +1 -0
- package/dist/legacy-sdpub/upgrade.d.ts +7 -0
- package/dist/legacy-sdpub/upgrade.js +795 -0
- package/dist/legacy-sdpub/upgrade.js.map +1 -0
- package/dist/llm/cache.d.ts +13 -0
- package/dist/llm/cache.js +35 -0
- package/dist/llm/cache.js.map +1 -0
- package/dist/llm/client.d.ts +26 -0
- package/dist/llm/client.js +572 -0
- package/dist/llm/client.js.map +1 -0
- package/dist/llm/context.d.ts +22 -0
- package/dist/llm/context.js +78 -0
- package/dist/llm/context.js.map +1 -0
- package/dist/llm/errors.d.ts +7 -0
- package/dist/llm/errors.js +12 -0
- package/dist/llm/errors.js.map +1 -0
- package/dist/llm/index.d.ts +7 -0
- package/dist/llm/index.js +17 -0
- package/dist/llm/index.js.map +1 -0
- package/dist/llm/request-log.d.ts +9 -0
- package/dist/llm/request-log.js +35 -0
- package/dist/llm/request-log.js.map +1 -0
- package/dist/llm/sampling.d.ts +11 -0
- package/dist/llm/sampling.js +67 -0
- package/dist/llm/sampling.js.map +1 -0
- package/dist/llm/types.d.ts +50 -0
- package/dist/llm/types.js +1 -0
- package/dist/llm/types.js.map +1 -0
- package/dist/output/epub/archive.d.ts +9 -0
- package/dist/output/epub/archive.js +81 -0
- package/dist/output/epub/archive.js.map +1 -0
- package/dist/output/epub/book.d.ts +15 -0
- package/dist/output/epub/book.js +76 -0
- package/dist/output/epub/book.js.map +1 -0
- package/dist/output/epub/content.d.ts +9 -0
- package/dist/output/epub/content.js +35 -0
- package/dist/output/epub/content.js.map +1 -0
- package/dist/output/epub/index.d.ts +20 -0
- package/dist/output/epub/index.js +14 -0
- package/dist/output/epub/index.js.map +1 -0
- package/dist/output/epub/model.d.ts +24 -0
- package/dist/output/epub/model.js +1 -0
- package/dist/output/epub/model.js.map +1 -0
- package/dist/output/epub/navigation.d.ts +10 -0
- package/dist/output/epub/navigation.js +39 -0
- package/dist/output/epub/navigation.js.map +1 -0
- package/dist/output/epub/package.d.ts +17 -0
- package/dist/output/epub/package.js +29 -0
- package/dist/output/epub/package.js.map +1 -0
- package/dist/output/epub/shared.d.ts +4 -0
- package/dist/output/epub/shared.js +12 -0
- package/dist/output/epub/shared.js.map +1 -0
- package/dist/output/epub/templates.d.ts +35 -0
- package/dist/output/epub/templates.js +26 -0
- package/dist/output/epub/templates.js.map +1 -0
- package/dist/output/index.d.ts +14 -0
- package/dist/output/index.js +11 -0
- package/dist/output/index.js.map +1 -0
- package/dist/output/plain-text.d.ts +18 -0
- package/dist/output/plain-text.js +56 -0
- package/dist/output/plain-text.js.map +1 -0
- package/dist/progress/index.d.ts +3 -0
- package/dist/progress/index.js +14 -0
- package/dist/progress/index.js.map +1 -0
- package/dist/progress/reporter.d.ts +10 -0
- package/dist/progress/reporter.js +79 -0
- package/dist/progress/reporter.js.map +1 -0
- package/dist/progress/tracker.d.ts +37 -0
- package/dist/progress/tracker.js +119 -0
- package/dist/progress/tracker.js.map +1 -0
- package/dist/progress/types.d.ts +28 -0
- package/dist/progress/types.js +1 -0
- package/dist/progress/types.js.map +1 -0
- package/dist/reader/attention/attention.d.ts +39 -0
- package/dist/reader/attention/attention.js +123 -0
- package/dist/reader/attention/attention.js.map +1 -0
- package/dist/reader/attention/index.d.ts +9 -0
- package/dist/reader/attention/index.js +5 -0
- package/dist/reader/attention/index.js.map +1 -0
- package/dist/reader/attention/wave-reflection.d.ts +21 -0
- package/dist/reader/attention/wave-reflection.js +153 -0
- package/dist/reader/attention/wave-reflection.js.map +1 -0
- package/dist/reader/attention/working-memory.d.ts +28 -0
- package/dist/reader/attention/working-memory.js +62 -0
- package/dist/reader/attention/working-memory.js.map +1 -0
- package/dist/reader/chunk-batch/extract.d.ts +13 -0
- package/dist/reader/chunk-batch/extract.js +14 -0
- package/dist/reader/chunk-batch/extract.js.map +1 -0
- package/dist/reader/chunk-batch/extractor.d.ts +17 -0
- package/dist/reader/chunk-batch/extractor.js +337 -0
- package/dist/reader/chunk-batch/extractor.js.map +1 -0
- package/dist/reader/chunk-batch/fragment-projection.d.ts +34 -0
- package/dist/reader/chunk-batch/fragment-projection.js +94 -0
- package/dist/reader/chunk-batch/fragment-projection.js.map +1 -0
- package/dist/reader/chunk-batch/index.d.ts +12 -0
- package/dist/reader/chunk-batch/index.js +13 -0
- package/dist/reader/chunk-batch/index.js.map +1 -0
- package/dist/reader/chunk-batch/language.d.ts +9 -0
- package/dist/reader/chunk-batch/language.js +23 -0
- package/dist/reader/chunk-batch/language.js.map +1 -0
- package/dist/reader/chunk-batch/parser.d.ts +94 -0
- package/dist/reader/chunk-batch/parser.js +640 -0
- package/dist/reader/chunk-batch/parser.js.map +1 -0
- package/dist/reader/chunk-batch/prompt-templates.d.ts +6 -0
- package/dist/reader/chunk-batch/prompt-templates.js +11 -0
- package/dist/reader/chunk-batch/prompt-templates.js.map +1 -0
- package/dist/reader/chunk-batch/types.d.ts +85 -0
- package/dist/reader/chunk-batch/types.js +1 -0
- package/dist/reader/chunk-batch/types.js.map +1 -0
- package/dist/reader/index.d.ts +13 -0
- package/dist/reader/index.js +7 -0
- package/dist/reader/index.js.map +1 -0
- package/dist/reader/reader.d.ts +37 -0
- package/dist/reader/reader.js +82 -0
- package/dist/reader/reader.js.map +1 -0
- package/dist/reader/segment/index.d.ts +2 -0
- package/dist/reader/segment/index.js +5 -0
- package/dist/reader/segment/index.js.map +1 -0
- package/dist/reader/segment/intl-segmenter.d.ts +5 -0
- package/dist/reader/segment/intl-segmenter.js +102 -0
- package/dist/reader/segment/intl-segmenter.js.map +1 -0
- package/dist/reader/segment/segment.d.ts +5 -0
- package/dist/reader/segment/segment.js +9 -0
- package/dist/reader/segment/segment.js.map +1 -0
- package/dist/reader/segment/types.d.ts +14 -0
- package/dist/reader/segment/types.js +1 -0
- package/dist/reader/segment/types.js.map +1 -0
- package/dist/reader/types.d.ts +29 -0
- package/dist/reader/types.js +1 -0
- package/dist/reader/types.js.map +1 -0
- package/dist/serial.d.ts +89 -0
- package/dist/serial.js +476 -0
- package/dist/serial.js.map +1 -0
- package/dist/source/adapter.d.ts +15 -0
- package/dist/source/adapter.js +1 -0
- package/dist/source/adapter.js.map +1 -0
- package/dist/source/epub/archive.d.ts +27 -0
- package/dist/source/epub/archive.js +189 -0
- package/dist/source/epub/archive.js.map +1 -0
- package/dist/source/epub/content.d.ts +22 -0
- package/dist/source/epub/content.js +183 -0
- package/dist/source/epub/content.js.map +1 -0
- package/dist/source/epub/document.d.ts +55 -0
- package/dist/source/epub/document.js +179 -0
- package/dist/source/epub/document.js.map +1 -0
- package/dist/source/epub/index.d.ts +10 -0
- package/dist/source/epub/index.js +6 -0
- package/dist/source/epub/index.js.map +1 -0
- package/dist/source/epub/navigation.d.ts +16 -0
- package/dist/source/epub/navigation.js +215 -0
- package/dist/source/epub/navigation.js.map +1 -0
- package/dist/source/epub/package.d.ts +33 -0
- package/dist/source/epub/package.js +237 -0
- package/dist/source/epub/package.js.map +1 -0
- package/dist/source/epub/xml.d.ts +16 -0
- package/dist/source/epub/xml.js +111 -0
- package/dist/source/epub/xml.js.map +1 -0
- package/dist/source/index.d.ts +12 -0
- package/dist/source/index.js +32 -0
- package/dist/source/index.js.map +1 -0
- package/dist/source/meta.d.ts +30 -0
- package/dist/source/meta.js +22 -0
- package/dist/source/meta.js.map +1 -0
- package/dist/source/plain-text.d.ts +16 -0
- package/dist/source/plain-text.js +86 -0
- package/dist/source/plain-text.js.map +1 -0
- package/dist/source/toc.d.ts +16 -0
- package/dist/source/toc.js +17 -0
- package/dist/source/toc.js.map +1 -0
- package/dist/source/types.d.ts +16 -0
- package/dist/source/types.js +1 -0
- package/dist/source/types.js.map +1 -0
- package/dist/topology/grouping.d.ts +15 -0
- package/dist/topology/grouping.js +18 -0
- package/dist/topology/grouping.js.map +1 -0
- package/dist/topology/index.d.ts +21 -0
- package/dist/topology/index.js +5 -0
- package/dist/topology/index.js.map +1 -0
- package/dist/topology/resource-segmentation.d.ts +13 -0
- package/dist/topology/resource-segmentation.js +111 -0
- package/dist/topology/resource-segmentation.js.map +1 -0
- package/dist/topology/segment-incision.d.ts +18 -0
- package/dist/topology/segment-incision.js +197 -0
- package/dist/topology/segment-incision.js.map +1 -0
- package/dist/topology/snake-detector.d.ts +13 -0
- package/dist/topology/snake-detector.js +520 -0
- package/dist/topology/snake-detector.js.map +1 -0
- package/dist/topology/snake-graph-builder.d.ts +14 -0
- package/dist/topology/snake-graph-builder.js +76 -0
- package/dist/topology/snake-graph-builder.js.map +1 -0
- package/dist/topology/topology.d.ts +29 -0
- package/dist/topology/topology.js +348 -0
- package/dist/topology/topology.js.map +1 -0
- package/dist/topology/weights.d.ts +10 -0
- package/dist/topology/weights.js +84 -0
- package/dist/topology/weights.js.map +1 -0
- package/dist/types-FVIqiLC9.d.cts +24 -0
- package/dist/utils/async-semaphore.d.ts +7 -0
- package/dist/utils/async-semaphore.js +40 -0
- package/dist/utils/async-semaphore.js.map +1 -0
- package/dist/utils/enum.d.ts +5 -0
- package/dist/utils/enum.js +18 -0
- package/dist/utils/enum.js.map +1 -0
- package/dist/utils/hash.d.ts +3 -0
- package/dist/utils/hash.js +132 -0
- package/dist/utils/hash.js.map +1 -0
- package/dist/utils/node-error.d.ts +4 -0
- package/dist/utils/node-error.js +59 -0
- package/dist/utils/node-error.js.map +1 -0
- package/dist/wikg/archive-uri.d.ts +1 -0
- package/dist/wikg/archive-uri.js +37 -0
- package/dist/wikg/archive-uri.js.map +1 -0
- package/dist/wikg/archive.d.ts +28 -0
- package/dist/wikg/archive.js +496 -0
- package/dist/wikg/archive.js.map +1 -0
- package/dist/wikg/index.d.ts +31 -0
- package/dist/wikg/index.js +60 -0
- package/dist/wikg/index.js.map +1 -0
- package/dist/wikg/wikg-coordinator.d.ts +45 -0
- package/dist/wikg/wikg-coordinator.js +1687 -0
- package/dist/wikg/wikg-coordinator.js.map +1 -0
- package/dist/wikg/wiki-graph-archive-file.d.ts +42 -0
- package/dist/wikg/wiki-graph-archive-file.js +78 -0
- package/dist/wikg/wiki-graph-archive-file.js.map +1 -0
- package/dist/wikilink/index.d.ts +10 -0
- package/dist/wikilink/index.js +7 -0
- package/dist/wikilink/index.js.map +1 -0
- package/dist/wikilink/relation-discovery.d.ts +31 -0
- package/dist/wikilink/relation-discovery.js +477 -0
- package/dist/wikilink/relation-discovery.js.map +1 -0
- package/dist/wikilink/types.d.ts +23 -0
- package/dist/wikilink/types.js +1 -0
- package/dist/wikilink/types.js.map +1 -0
- package/dist/wikilink/window.d.ts +7 -0
- package/dist/wikilink/window.js +53 -0
- package/dist/wikilink/window.js.map +1 -0
- package/dist/wikimatch/enrichment.d.ts +10 -0
- package/dist/wikimatch/enrichment.js +55 -0
- package/dist/wikimatch/enrichment.js.map +1 -0
- package/dist/wikimatch/index.d.ts +16 -0
- package/dist/wikimatch/index.js +66 -0
- package/dist/wikimatch/index.js.map +1 -0
- package/dist/wikimatch/option-narrowing.d.ts +17 -0
- package/dist/wikimatch/option-narrowing.js +208 -0
- package/dist/wikimatch/option-narrowing.js.map +1 -0
- package/dist/wikimatch/options.d.ts +14 -0
- package/dist/wikimatch/options.js +155 -0
- package/dist/wikimatch/options.js.map +1 -0
- package/dist/wikimatch/policy-judge.d.ts +17 -0
- package/dist/wikimatch/policy-judge.js +430 -0
- package/dist/wikimatch/policy-judge.js.map +1 -0
- package/dist/wikimatch/range-suppression.d.ts +9 -0
- package/dist/wikimatch/range-suppression.js +27 -0
- package/dist/wikimatch/range-suppression.js.map +1 -0
- package/dist/wikimatch/surface-screening.d.ts +16 -0
- package/dist/wikimatch/surface-screening.js +168 -0
- package/dist/wikimatch/surface-screening.js.map +1 -0
- package/dist/wikimatch/surface-window.d.ts +6 -0
- package/dist/wikimatch/surface-window.js +44 -0
- package/dist/wikimatch/surface-window.js.map +1 -0
- package/dist/wikimatch/types.d.ts +151 -0
- package/dist/wikimatch/types.js +1 -0
- package/dist/wikimatch/types.js.map +1 -0
- package/dist/wikimatch/wikispine.d.ts +43 -0
- package/dist/wikimatch/wikispine.js +399 -0
- package/dist/wikimatch/wikispine.js.map +1 -0
- package/dist/wikimatch/window.d.ts +6 -0
- package/dist/wikimatch/window.js +83 -0
- package/dist/wikimatch/window.js.map +1 -0
- package/dist/wikimatch/words.d.ts +16 -0
- package/dist/wikimatch/words.js +66 -0
- package/dist/wikimatch/words.js.map +1 -0
- package/dist/wikipage/cache.d.ts +18 -0
- package/dist/wikipage/cache.js +404 -0
- package/dist/wikipage/cache.js.map +1 -0
- package/dist/wikipage/fetch-log.d.ts +17 -0
- package/dist/wikipage/fetch-log.js +143 -0
- package/dist/wikipage/fetch-log.js.map +1 -0
- package/dist/wikipage/index.d.ts +14 -0
- package/dist/wikipage/index.js +17 -0
- package/dist/wikipage/index.js.map +1 -0
- package/dist/wikipage/normalizer.d.ts +14 -0
- package/dist/wikipage/normalizer.js +147 -0
- package/dist/wikipage/normalizer.js.map +1 -0
- package/dist/wikipage/rate-limiter.d.ts +13 -0
- package/dist/wikipage/rate-limiter.js +84 -0
- package/dist/wikipage/rate-limiter.js.map +1 -0
- package/dist/wikipage/resolver.d.ts +26 -0
- package/dist/wikipage/resolver.js +325 -0
- package/dist/wikipage/resolver.js.map +1 -0
- package/dist/wikipage/types.d.ts +96 -0
- package/dist/wikipage/types.js +1 -0
- package/dist/wikipage/types.js.map +1 -0
- package/dist/wikipage/wikimedia-client.d.ts +48 -0
- package/dist/wikipage/wikimedia-client.js +397 -0
- package/dist/wikipage/wikimedia-client.js.map +1 -0
- package/dist/worker-BgQ0Xl8T.d.cts +181 -0
- package/dist/worker.cjs +5259 -0
- package/dist/worker.cjs.map +1 -0
- package/dist/worker.d.cts +2 -0
- package/dist/worker.d.ts +2 -0
- package/dist/worker.js +5 -0
- package/dist/worker.js.map +1 -0
- package/package.json +78 -0
|
@@ -0,0 +1,515 @@
|
|
|
1
|
+
import { mkdir, readFile, readdir, rm, writeFile } from "fs/promises";
|
|
2
|
+
import { join, resolve } from "path";
|
|
3
|
+
import { isNodeError } from "../utils/node-error.js";
|
|
4
|
+
import {
|
|
5
|
+
Sentence
|
|
6
|
+
} from "./types.js";
|
|
7
|
+
const DEFAULT_FRAGMENT_WORDS_COUNT = 600;
|
|
8
|
+
const TEXT_STREAM_KIND = {
|
|
9
|
+
source: 1,
|
|
10
|
+
summary: 2
|
|
11
|
+
};
|
|
12
|
+
const DEFAULT_FILE_ACCESS = {
|
|
13
|
+
deleteTree: async (path) => {
|
|
14
|
+
await rm(path, { force: true, recursive: true });
|
|
15
|
+
},
|
|
16
|
+
ensureDirectory: async (path) => {
|
|
17
|
+
await mkdir(path, { recursive: true });
|
|
18
|
+
},
|
|
19
|
+
listFiles: async (path) => (await readdir(path, { withFileTypes: true })).filter((entry) => entry.isFile()).map((entry) => entry.name),
|
|
20
|
+
readFile: async (path) => {
|
|
21
|
+
try {
|
|
22
|
+
return await readFile(path);
|
|
23
|
+
} catch (error) {
|
|
24
|
+
if (isNodeError(error) && error.code === "ENOENT") {
|
|
25
|
+
return void 0;
|
|
26
|
+
}
|
|
27
|
+
throw error;
|
|
28
|
+
}
|
|
29
|
+
},
|
|
30
|
+
writeFile: async (path, content, options) => {
|
|
31
|
+
await writeFile(path, content, {
|
|
32
|
+
...typeof content === "string" ? { encoding: "utf8" } : {},
|
|
33
|
+
flag: options.overwrite === true ? "w" : "wx"
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
};
|
|
37
|
+
class TextStreams {
|
|
38
|
+
#database;
|
|
39
|
+
#documentPath;
|
|
40
|
+
#fileAccess;
|
|
41
|
+
constructor(documentPath, database, fileAccess = DEFAULT_FILE_ACCESS) {
|
|
42
|
+
this.#database = database;
|
|
43
|
+
this.#documentPath = resolve(documentPath);
|
|
44
|
+
this.#fileAccess = fileAccess;
|
|
45
|
+
}
|
|
46
|
+
async ensureCreated() {
|
|
47
|
+
await this.#fileAccess.ensureDirectory(this.#getRootPath("source"));
|
|
48
|
+
await this.#fileAccess.ensureDirectory(this.#getRootPath("summary"));
|
|
49
|
+
}
|
|
50
|
+
async getSentence(sentenceId) {
|
|
51
|
+
return (await this.getSerial(sentenceId[0]).getSentence(sentenceId[1])).text;
|
|
52
|
+
}
|
|
53
|
+
getSerial(serialId) {
|
|
54
|
+
return new SerialTextStream(
|
|
55
|
+
this.#documentPath,
|
|
56
|
+
this.#database,
|
|
57
|
+
this.#fileAccess,
|
|
58
|
+
"source",
|
|
59
|
+
serialId
|
|
60
|
+
);
|
|
61
|
+
}
|
|
62
|
+
getSummarySerial(serialId) {
|
|
63
|
+
return new SerialTextStream(
|
|
64
|
+
this.#documentPath,
|
|
65
|
+
this.#database,
|
|
66
|
+
this.#fileAccess,
|
|
67
|
+
"summary",
|
|
68
|
+
serialId
|
|
69
|
+
);
|
|
70
|
+
}
|
|
71
|
+
#getRootPath(stream) {
|
|
72
|
+
return join(this.#documentPath, "texts", stream);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
class SerialTextStream {
|
|
76
|
+
static #draftStates = /* @__PURE__ */ new Map();
|
|
77
|
+
#database;
|
|
78
|
+
#documentPath;
|
|
79
|
+
#fileAccess;
|
|
80
|
+
#stream;
|
|
81
|
+
#serialId;
|
|
82
|
+
constructor(documentPath, database, fileAccess, stream, serialId) {
|
|
83
|
+
this.#database = database;
|
|
84
|
+
this.#documentPath = resolve(documentPath);
|
|
85
|
+
this.#fileAccess = fileAccess;
|
|
86
|
+
this.#stream = stream;
|
|
87
|
+
this.#serialId = serialId;
|
|
88
|
+
}
|
|
89
|
+
async createDraft() {
|
|
90
|
+
const draftState = this.#getDraftState();
|
|
91
|
+
if (draftState.draftOpen) {
|
|
92
|
+
throw new Error("Only one text stream draft can be open at a time");
|
|
93
|
+
}
|
|
94
|
+
await this.#fileAccess.ensureDirectory(this.#getDirectoryPath());
|
|
95
|
+
draftState.draftOpen = true;
|
|
96
|
+
return new TextStreamDraft(this.#serialId, await this.#peekNextIndex(), {
|
|
97
|
+
discard: () => {
|
|
98
|
+
draftState.draftOpen = false;
|
|
99
|
+
},
|
|
100
|
+
finalize: async (startIndex, summary, sentences) => await this.#commitDraft(startIndex, summary, sentences)
|
|
101
|
+
});
|
|
102
|
+
}
|
|
103
|
+
async getFragment(fragmentId) {
|
|
104
|
+
const fragments = await this.#listFragments();
|
|
105
|
+
const fragment = fragments.find((item) => item.fragmentId === fragmentId);
|
|
106
|
+
if (fragment === void 0) {
|
|
107
|
+
throw new Error(`Fragment ${fragmentId} does not exist`);
|
|
108
|
+
}
|
|
109
|
+
return fragment;
|
|
110
|
+
}
|
|
111
|
+
async getSentence(sentenceIndex) {
|
|
112
|
+
const location = await this.#getSentenceLocation(sentenceIndex);
|
|
113
|
+
if (location === void 0) {
|
|
114
|
+
throw new RangeError(`Sentence ${sentenceIndex} does not exist`);
|
|
115
|
+
}
|
|
116
|
+
return this.#readSentenceLocation(location, await this.#readContent());
|
|
117
|
+
}
|
|
118
|
+
async listFragmentIds() {
|
|
119
|
+
return (await this.#listFragments()).map((fragment) => fragment.fragmentId);
|
|
120
|
+
}
|
|
121
|
+
async listSentences() {
|
|
122
|
+
const rows = await this.#listSentenceLocations();
|
|
123
|
+
const content = await this.#readContent();
|
|
124
|
+
return rows.map((row) => this.#readSentenceLocation(row, content));
|
|
125
|
+
}
|
|
126
|
+
async listSentencesInRange(startSentenceIndex, endSentenceIndex) {
|
|
127
|
+
if (endSentenceIndex < startSentenceIndex) {
|
|
128
|
+
return [];
|
|
129
|
+
}
|
|
130
|
+
const rows = await this.#database.queryAll(
|
|
131
|
+
`
|
|
132
|
+
SELECT sentence_index, byte_offset, byte_length, words_count
|
|
133
|
+
FROM text_sentence_records
|
|
134
|
+
WHERE kind = ? AND chapter_id = ?
|
|
135
|
+
AND sentence_index BETWEEN ? AND ?
|
|
136
|
+
ORDER BY sentence_index
|
|
137
|
+
`,
|
|
138
|
+
[
|
|
139
|
+
TEXT_STREAM_KIND[this.#stream],
|
|
140
|
+
this.#serialId,
|
|
141
|
+
startSentenceIndex,
|
|
142
|
+
endSentenceIndex
|
|
143
|
+
],
|
|
144
|
+
mapTextSentenceLocation
|
|
145
|
+
);
|
|
146
|
+
const content = await this.#readContent();
|
|
147
|
+
return rows.map((row) => this.#readSentenceLocation(row, content));
|
|
148
|
+
}
|
|
149
|
+
async readTextInRange(startSentenceIndex, endSentenceIndex) {
|
|
150
|
+
if (endSentenceIndex < startSentenceIndex) {
|
|
151
|
+
return "";
|
|
152
|
+
}
|
|
153
|
+
const rows = await this.#database.queryAll(
|
|
154
|
+
`
|
|
155
|
+
SELECT sentence_index, byte_offset, byte_length, words_count
|
|
156
|
+
FROM text_sentence_records
|
|
157
|
+
WHERE kind = ? AND chapter_id = ?
|
|
158
|
+
AND sentence_index BETWEEN ? AND ?
|
|
159
|
+
ORDER BY sentence_index
|
|
160
|
+
`,
|
|
161
|
+
[
|
|
162
|
+
TEXT_STREAM_KIND[this.#stream],
|
|
163
|
+
this.#serialId,
|
|
164
|
+
startSentenceIndex,
|
|
165
|
+
endSentenceIndex
|
|
166
|
+
],
|
|
167
|
+
mapTextSentenceLocation
|
|
168
|
+
);
|
|
169
|
+
const first = rows[0];
|
|
170
|
+
const last = rows[rows.length - 1];
|
|
171
|
+
if (first === void 0 || last === void 0) {
|
|
172
|
+
return void 0;
|
|
173
|
+
}
|
|
174
|
+
const content = await this.#readContent();
|
|
175
|
+
return content.subarray(first.byteOffset, last.byteOffset + last.byteLength).toString("utf8");
|
|
176
|
+
}
|
|
177
|
+
async #getSentenceLocation(sentenceIndex) {
|
|
178
|
+
return await this.#database.queryOne(
|
|
179
|
+
`
|
|
180
|
+
SELECT sentence_index, byte_offset, byte_length, words_count
|
|
181
|
+
FROM text_sentence_records
|
|
182
|
+
WHERE kind = ? AND chapter_id = ? AND sentence_index = ?
|
|
183
|
+
`,
|
|
184
|
+
[TEXT_STREAM_KIND[this.#stream], this.#serialId, sentenceIndex],
|
|
185
|
+
mapTextSentenceLocation
|
|
186
|
+
);
|
|
187
|
+
}
|
|
188
|
+
async #listSentenceLocations() {
|
|
189
|
+
return await this.#database.queryAll(
|
|
190
|
+
`
|
|
191
|
+
SELECT sentence_index, byte_offset, byte_length, words_count
|
|
192
|
+
FROM text_sentence_records
|
|
193
|
+
WHERE kind = ? AND chapter_id = ?
|
|
194
|
+
ORDER BY sentence_index
|
|
195
|
+
`,
|
|
196
|
+
[TEXT_STREAM_KIND[this.#stream], this.#serialId],
|
|
197
|
+
mapTextSentenceLocation
|
|
198
|
+
);
|
|
199
|
+
}
|
|
200
|
+
#readSentenceLocation(location, content) {
|
|
201
|
+
return new Sentence(
|
|
202
|
+
content.subarray(
|
|
203
|
+
location.byteOffset,
|
|
204
|
+
location.byteOffset + location.byteLength
|
|
205
|
+
).toString("utf8"),
|
|
206
|
+
location.wordsCount
|
|
207
|
+
);
|
|
208
|
+
}
|
|
209
|
+
async readText() {
|
|
210
|
+
const content = await this.#fileAccess.readFile(this.#getTextPath());
|
|
211
|
+
return content === void 0 ? void 0 : Buffer.from(content).toString("utf8");
|
|
212
|
+
}
|
|
213
|
+
async writeTextStream(text, options = {}) {
|
|
214
|
+
await this.delete();
|
|
215
|
+
const sentences = await splitTextIntoSentenceSpans(text, options.segmenter);
|
|
216
|
+
const draft = await this.createDraft();
|
|
217
|
+
for (const sentence of sentences) {
|
|
218
|
+
draft.addSentence(sentence.text, sentence.wordsCount, {
|
|
219
|
+
byteOffset: sentence.byteOffset,
|
|
220
|
+
byteLength: sentence.byteLength
|
|
221
|
+
});
|
|
222
|
+
}
|
|
223
|
+
await draft.commitWithText(text);
|
|
224
|
+
}
|
|
225
|
+
async delete() {
|
|
226
|
+
await this.#fileAccess.deleteTree(this.#getTextPath());
|
|
227
|
+
await this.#database.run(
|
|
228
|
+
`
|
|
229
|
+
DELETE FROM text_sentence_records
|
|
230
|
+
WHERE kind = ? AND chapter_id = ?
|
|
231
|
+
`,
|
|
232
|
+
[TEXT_STREAM_KIND[this.#stream], this.#serialId]
|
|
233
|
+
);
|
|
234
|
+
delete this.#getDraftState().nextSentenceIndex;
|
|
235
|
+
}
|
|
236
|
+
get path() {
|
|
237
|
+
return this.#getTextPath();
|
|
238
|
+
}
|
|
239
|
+
get serialId() {
|
|
240
|
+
return this.#serialId;
|
|
241
|
+
}
|
|
242
|
+
async #commitDraft(startIndex, textOverride, sentences) {
|
|
243
|
+
const draftState = this.#getDraftState();
|
|
244
|
+
draftState.draftOpen = false;
|
|
245
|
+
const existing = await this.#fileAccess.readFile(this.#getTextPath());
|
|
246
|
+
const existingBuffer = existing === void 0 ? Buffer.alloc(0) : Buffer.from(existing);
|
|
247
|
+
const text = textOverride === "" ? sentences.map(getSentenceRawText).join("") : textOverride;
|
|
248
|
+
const appendBuffer = Buffer.from(text, "utf8");
|
|
249
|
+
let offset = existingBuffer.length;
|
|
250
|
+
await this.#fileAccess.ensureDirectory(this.#getDirectoryPath());
|
|
251
|
+
await this.#fileAccess.writeFile(
|
|
252
|
+
this.#getTextPath(),
|
|
253
|
+
Buffer.concat([existingBuffer, appendBuffer]),
|
|
254
|
+
{ overwrite: true }
|
|
255
|
+
);
|
|
256
|
+
if (sentences.length === 0) {
|
|
257
|
+
return void 0;
|
|
258
|
+
}
|
|
259
|
+
for (let index = 0; index < sentences.length; index += 1) {
|
|
260
|
+
const sentence = sentences[index];
|
|
261
|
+
if (sentence === void 0) {
|
|
262
|
+
continue;
|
|
263
|
+
}
|
|
264
|
+
const length = getSentenceByteLength(sentence);
|
|
265
|
+
const explicitOffset = getSentenceByteOffset(sentence);
|
|
266
|
+
const sentenceOffset = offset + explicitOffset;
|
|
267
|
+
await this.#database.run(
|
|
268
|
+
`
|
|
269
|
+
INSERT OR REPLACE INTO text_sentence_records (
|
|
270
|
+
kind,
|
|
271
|
+
chapter_id,
|
|
272
|
+
sentence_index,
|
|
273
|
+
words_count,
|
|
274
|
+
byte_offset,
|
|
275
|
+
byte_length
|
|
276
|
+
)
|
|
277
|
+
VALUES (?, ?, ?, ?, ?, ?)
|
|
278
|
+
`,
|
|
279
|
+
[
|
|
280
|
+
TEXT_STREAM_KIND[this.#stream],
|
|
281
|
+
this.#serialId,
|
|
282
|
+
startIndex + index,
|
|
283
|
+
sentence.wordsCount,
|
|
284
|
+
sentenceOffset,
|
|
285
|
+
length
|
|
286
|
+
]
|
|
287
|
+
);
|
|
288
|
+
if (!hasSentenceByteOffset(sentence)) {
|
|
289
|
+
offset += length;
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
draftState.nextSentenceIndex = startIndex + sentences.length;
|
|
293
|
+
return {
|
|
294
|
+
fragmentId: startIndex,
|
|
295
|
+
sentences,
|
|
296
|
+
serialId: this.#serialId,
|
|
297
|
+
summary: ""
|
|
298
|
+
};
|
|
299
|
+
}
|
|
300
|
+
async #listFragments() {
|
|
301
|
+
const sentences = await this.listSentences();
|
|
302
|
+
const fragments = [];
|
|
303
|
+
let current = [];
|
|
304
|
+
let currentWords = 0;
|
|
305
|
+
let fragmentStart = 0;
|
|
306
|
+
for (let index = 0; index < sentences.length; index += 1) {
|
|
307
|
+
const sentence = sentences[index];
|
|
308
|
+
if (sentence === void 0) {
|
|
309
|
+
continue;
|
|
310
|
+
}
|
|
311
|
+
if (current.length > 0 && currentWords + sentence.wordsCount > DEFAULT_FRAGMENT_WORDS_COUNT) {
|
|
312
|
+
fragments.push({
|
|
313
|
+
fragmentId: fragmentStart,
|
|
314
|
+
sentences: current,
|
|
315
|
+
serialId: this.#serialId,
|
|
316
|
+
summary: ""
|
|
317
|
+
});
|
|
318
|
+
fragmentStart = index;
|
|
319
|
+
current = [];
|
|
320
|
+
currentWords = 0;
|
|
321
|
+
}
|
|
322
|
+
current.push(sentence);
|
|
323
|
+
currentWords += sentence.wordsCount;
|
|
324
|
+
}
|
|
325
|
+
if (current.length > 0) {
|
|
326
|
+
fragments.push({
|
|
327
|
+
fragmentId: fragmentStart,
|
|
328
|
+
sentences: current,
|
|
329
|
+
serialId: this.#serialId,
|
|
330
|
+
summary: ""
|
|
331
|
+
});
|
|
332
|
+
}
|
|
333
|
+
return fragments;
|
|
334
|
+
}
|
|
335
|
+
async #peekNextIndex() {
|
|
336
|
+
const draftState = this.#getDraftState();
|
|
337
|
+
if (draftState.nextSentenceIndex !== void 0) {
|
|
338
|
+
return draftState.nextSentenceIndex;
|
|
339
|
+
}
|
|
340
|
+
draftState.nextSentenceIndex = await this.#database.queryOne(
|
|
341
|
+
`
|
|
342
|
+
SELECT COALESCE(MAX(sentence_index), -1) + 1 AS next_index
|
|
343
|
+
FROM text_sentence_records
|
|
344
|
+
WHERE kind = ? AND chapter_id = ?
|
|
345
|
+
`,
|
|
346
|
+
[TEXT_STREAM_KIND[this.#stream], this.#serialId],
|
|
347
|
+
(row) => Number(row.next_index)
|
|
348
|
+
) ?? 0;
|
|
349
|
+
return draftState.nextSentenceIndex;
|
|
350
|
+
}
|
|
351
|
+
async #readContent() {
|
|
352
|
+
const content = await this.#fileAccess.readFile(this.#getTextPath());
|
|
353
|
+
return Buffer.from(content ?? new Uint8Array());
|
|
354
|
+
}
|
|
355
|
+
#getDirectoryPath() {
|
|
356
|
+
return join(this.#documentPath, "texts", this.#stream);
|
|
357
|
+
}
|
|
358
|
+
#getTextPath() {
|
|
359
|
+
return join(this.#getDirectoryPath(), `${this.#serialId}.txt`);
|
|
360
|
+
}
|
|
361
|
+
#getDraftState() {
|
|
362
|
+
const key = `${this.#documentPath}\0${this.#stream}\0${this.#serialId}`;
|
|
363
|
+
let state = SerialTextStream.#draftStates.get(key);
|
|
364
|
+
if (state === void 0) {
|
|
365
|
+
state = { draftOpen: false };
|
|
366
|
+
SerialTextStream.#draftStates.set(key, state);
|
|
367
|
+
}
|
|
368
|
+
return state;
|
|
369
|
+
}
|
|
370
|
+
}
|
|
371
|
+
function mapTextSentenceLocation(row) {
|
|
372
|
+
return {
|
|
373
|
+
byteLength: Number(row.byte_length),
|
|
374
|
+
byteOffset: Number(row.byte_offset),
|
|
375
|
+
sentenceIndex: Number(row.sentence_index),
|
|
376
|
+
wordsCount: Number(row.words_count)
|
|
377
|
+
};
|
|
378
|
+
}
|
|
379
|
+
class TextStreamDraft {
|
|
380
|
+
#committed = false;
|
|
381
|
+
#discard;
|
|
382
|
+
#finalize;
|
|
383
|
+
#sentences = [];
|
|
384
|
+
#serialId;
|
|
385
|
+
#startSentenceIndex;
|
|
386
|
+
#summary = "";
|
|
387
|
+
constructor(serialId, startSentenceIndex, callbacks) {
|
|
388
|
+
this.#discard = callbacks.discard;
|
|
389
|
+
this.#finalize = callbacks.finalize;
|
|
390
|
+
this.#serialId = serialId;
|
|
391
|
+
this.#startSentenceIndex = startSentenceIndex;
|
|
392
|
+
}
|
|
393
|
+
addSentence(text, wordsCount, location) {
|
|
394
|
+
this.#assertActive();
|
|
395
|
+
const sentenceIndex = this.#startSentenceIndex + this.#sentences.length;
|
|
396
|
+
const sentence = new Sentence(text, wordsCount);
|
|
397
|
+
if (location !== void 0) {
|
|
398
|
+
Object.assign(sentence, {
|
|
399
|
+
byteLength: location.byteLength,
|
|
400
|
+
byteOffset: location.byteOffset
|
|
401
|
+
});
|
|
402
|
+
}
|
|
403
|
+
this.#sentences.push(sentence);
|
|
404
|
+
return [this.#serialId, sentenceIndex];
|
|
405
|
+
}
|
|
406
|
+
async commit() {
|
|
407
|
+
this.#assertActive();
|
|
408
|
+
this.#committed = true;
|
|
409
|
+
return await this.#finalize(
|
|
410
|
+
this.#startSentenceIndex,
|
|
411
|
+
this.#summary,
|
|
412
|
+
this.#sentences
|
|
413
|
+
);
|
|
414
|
+
}
|
|
415
|
+
async commitWithText(text) {
|
|
416
|
+
this.#assertActive();
|
|
417
|
+
this.#committed = true;
|
|
418
|
+
return await this.#finalize(
|
|
419
|
+
this.#startSentenceIndex,
|
|
420
|
+
text,
|
|
421
|
+
this.#sentences
|
|
422
|
+
);
|
|
423
|
+
}
|
|
424
|
+
discard() {
|
|
425
|
+
this.#assertActive();
|
|
426
|
+
this.#committed = true;
|
|
427
|
+
this.#discard();
|
|
428
|
+
}
|
|
429
|
+
setSummary(summary) {
|
|
430
|
+
this.#assertActive();
|
|
431
|
+
this.#summary = summary;
|
|
432
|
+
}
|
|
433
|
+
get fragmentId() {
|
|
434
|
+
return this.#startSentenceIndex;
|
|
435
|
+
}
|
|
436
|
+
#assertActive() {
|
|
437
|
+
if (this.#committed) {
|
|
438
|
+
throw new Error("Text stream draft is already finalized");
|
|
439
|
+
}
|
|
440
|
+
}
|
|
441
|
+
}
|
|
442
|
+
async function splitTextIntoSentenceSpans(text, segmenter) {
|
|
443
|
+
if (segmenter !== void 0) {
|
|
444
|
+
return await splitTextIntoCustomSentenceSpans(text, segmenter);
|
|
445
|
+
}
|
|
446
|
+
const spans = [];
|
|
447
|
+
for (const segment of createSentenceSegmenter().segment(text)) {
|
|
448
|
+
const rawText = segment.segment;
|
|
449
|
+
if (rawText.trim() === "") {
|
|
450
|
+
continue;
|
|
451
|
+
}
|
|
452
|
+
const sentence = new Sentence(rawText, countWords(rawText));
|
|
453
|
+
Object.assign(sentence, {
|
|
454
|
+
byteLength: Buffer.byteLength(rawText, "utf8"),
|
|
455
|
+
byteOffset: Buffer.byteLength(text.slice(0, segment.index), "utf8")
|
|
456
|
+
});
|
|
457
|
+
spans.push(
|
|
458
|
+
sentence
|
|
459
|
+
);
|
|
460
|
+
}
|
|
461
|
+
return spans;
|
|
462
|
+
}
|
|
463
|
+
async function splitTextIntoCustomSentenceSpans(text, segmenter) {
|
|
464
|
+
const spans = [];
|
|
465
|
+
for await (const segment of segmenter.pipe([text])) {
|
|
466
|
+
const rawText = text.slice(
|
|
467
|
+
segment.offset,
|
|
468
|
+
segment.offset + segment.text.length
|
|
469
|
+
);
|
|
470
|
+
if (rawText.trim() === "") {
|
|
471
|
+
continue;
|
|
472
|
+
}
|
|
473
|
+
const sentence = new Sentence(rawText, segment.wordsCount);
|
|
474
|
+
Object.assign(sentence, {
|
|
475
|
+
byteLength: Buffer.byteLength(rawText, "utf8"),
|
|
476
|
+
byteOffset: Buffer.byteLength(text.slice(0, segment.offset), "utf8")
|
|
477
|
+
});
|
|
478
|
+
spans.push(
|
|
479
|
+
sentence
|
|
480
|
+
);
|
|
481
|
+
}
|
|
482
|
+
return spans;
|
|
483
|
+
}
|
|
484
|
+
let SENTENCE_SEGMENTER;
|
|
485
|
+
function createSentenceSegmenter() {
|
|
486
|
+
SENTENCE_SEGMENTER ??= new Intl.Segmenter(void 0, {
|
|
487
|
+
granularity: "sentence"
|
|
488
|
+
});
|
|
489
|
+
return SENTENCE_SEGMENTER;
|
|
490
|
+
}
|
|
491
|
+
function countWords(text) {
|
|
492
|
+
const trimmed = text.trim();
|
|
493
|
+
return trimmed === "" ? 0 : trimmed.split(/\s+/u).length;
|
|
494
|
+
}
|
|
495
|
+
function getSentenceByteOffset(sentence) {
|
|
496
|
+
const value = sentence.byteOffset;
|
|
497
|
+
return typeof value === "number" ? value : 0;
|
|
498
|
+
}
|
|
499
|
+
function hasSentenceByteOffset(sentence) {
|
|
500
|
+
return typeof sentence.byteOffset === "number";
|
|
501
|
+
}
|
|
502
|
+
function getSentenceByteLength(sentence) {
|
|
503
|
+
const value = sentence.byteLength;
|
|
504
|
+
return typeof value === "number" ? value : Buffer.byteLength(getSentenceRawText(sentence), "utf8");
|
|
505
|
+
}
|
|
506
|
+
function getSentenceRawText(sentence) {
|
|
507
|
+
const value = sentence.rawText;
|
|
508
|
+
return typeof value === "string" ? value : sentence.text;
|
|
509
|
+
}
|
|
510
|
+
export {
|
|
511
|
+
SerialTextStream,
|
|
512
|
+
TextStreamDraft,
|
|
513
|
+
TextStreams
|
|
514
|
+
};
|
|
515
|
+
//# sourceMappingURL=text-streams.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/document/text-streams.ts"],"sourcesContent":["import { mkdir, readFile, readdir, rm, writeFile } from \"fs/promises\";\nimport { join, resolve } from \"path\";\n\nimport { isNodeError } from \"../utils/node-error.js\";\nimport type { Database } from \"./database.js\";\nimport {\n Sentence,\n type FragmentRecord,\n type SentenceId,\n type SentenceRecord,\n} from \"./types.js\";\n\nconst DEFAULT_FRAGMENT_WORDS_COUNT = 600;\nconst TEXT_STREAM_KIND = {\n source: 1,\n summary: 2,\n} as const;\n\ntype TextStreamName = keyof typeof TEXT_STREAM_KIND;\n\ninterface TextSentenceLocation {\n readonly byteLength: number;\n readonly byteOffset: number;\n readonly sentenceIndex: number;\n readonly wordsCount: number;\n}\n\ninterface TextStreamDraftState {\n draftOpen: boolean;\n nextSentenceIndex?: number;\n}\n\ninterface TextStreamFileAccess {\n deleteTree(path: string): Promise<void>;\n ensureDirectory(path: string): Promise<void>;\n listFiles(path: string): Promise<readonly string[]>;\n readFile(path: string): Promise<Uint8Array | undefined>;\n writeFile(\n path: string,\n content: string | Uint8Array,\n options: { readonly overwrite?: boolean },\n ): Promise<void>;\n}\n\ninterface TextStreamSentenceSegmenter {\n pipe(stream: Iterable<string>): AsyncIterable<{\n readonly offset: number;\n readonly text: string;\n readonly wordsCount: number;\n }>;\n}\n\ninterface WriteTextStreamOptions {\n readonly segmenter?: TextStreamSentenceSegmenter;\n}\n\nconst DEFAULT_FILE_ACCESS: TextStreamFileAccess = {\n deleteTree: async (path) => {\n await rm(path, { force: true, recursive: true });\n },\n ensureDirectory: async (path) => {\n await mkdir(path, { recursive: true });\n },\n listFiles: async (path) =>\n (await readdir(path, { withFileTypes: true }))\n .filter((entry) => entry.isFile())\n .map((entry) => entry.name),\n readFile: async (path) => {\n try {\n return await readFile(path);\n } catch (error) {\n if (isNodeError(error) && error.code === \"ENOENT\") {\n return undefined;\n }\n\n throw error;\n }\n },\n writeFile: async (path, content, options) => {\n await writeFile(path, content, {\n ...(typeof content === \"string\" ? { encoding: \"utf8\" as const } : {}),\n flag: options.overwrite === true ? \"w\" : \"wx\",\n });\n },\n};\n\nexport interface ReadonlyTextStreams {\n getSentence(sentenceId: SentenceId): Promise<string>;\n getSerial(serialId: number): ReadonlySerialTextStream;\n getSummarySerial(serialId: number): ReadonlySerialTextStream;\n}\n\nexport interface ReadonlySerialTextStream {\n getFragment(fragmentId: number): Promise<FragmentRecord>;\n getSentence?(sentenceIndex: number): Promise<SentenceRecord>;\n listSentencesInRange?(\n startSentenceIndex: number,\n endSentenceIndex: number,\n ): Promise<readonly SentenceRecord[]>;\n listFragmentIds(): Promise<readonly number[]>;\n listSentences?(): Promise<readonly SentenceRecord[]>;\n readText?(): Promise<string | undefined>;\n readTextInRange?(\n startSentenceIndex: number,\n endSentenceIndex: number,\n ): Promise<string | undefined>;\n readonly path: string;\n readonly serialId: number;\n}\n\nexport class TextStreams implements ReadonlyTextStreams {\n readonly #database: Database;\n readonly #documentPath: string;\n readonly #fileAccess: TextStreamFileAccess;\n\n public constructor(\n documentPath: string,\n database: Database,\n fileAccess: TextStreamFileAccess = DEFAULT_FILE_ACCESS,\n ) {\n this.#database = database;\n this.#documentPath = resolve(documentPath);\n this.#fileAccess = fileAccess;\n }\n\n public async ensureCreated(): Promise<void> {\n await this.#fileAccess.ensureDirectory(this.#getRootPath(\"source\"));\n await this.#fileAccess.ensureDirectory(this.#getRootPath(\"summary\"));\n }\n\n public async getSentence(sentenceId: SentenceId): Promise<string> {\n return (await this.getSerial(sentenceId[0]).getSentence(sentenceId[1]))\n .text;\n }\n\n public getSerial(serialId: number): SerialTextStream {\n return new SerialTextStream(\n this.#documentPath,\n this.#database,\n this.#fileAccess,\n \"source\",\n serialId,\n );\n }\n\n public getSummarySerial(serialId: number): SerialTextStream {\n return new SerialTextStream(\n this.#documentPath,\n this.#database,\n this.#fileAccess,\n \"summary\",\n serialId,\n );\n }\n\n #getRootPath(stream: TextStreamName): string {\n return join(this.#documentPath, \"texts\", stream);\n }\n}\n\nexport class SerialTextStream implements ReadonlySerialTextStream {\n static readonly #draftStates = new Map<string, TextStreamDraftState>();\n\n readonly #database: Database;\n readonly #documentPath: string;\n readonly #fileAccess: TextStreamFileAccess;\n readonly #stream: TextStreamName;\n readonly #serialId: number;\n\n public constructor(\n documentPath: string,\n database: Database,\n fileAccess: TextStreamFileAccess,\n stream: TextStreamName,\n serialId: number,\n ) {\n this.#database = database;\n this.#documentPath = resolve(documentPath);\n this.#fileAccess = fileAccess;\n this.#stream = stream;\n this.#serialId = serialId;\n }\n\n public async createDraft(): Promise<TextStreamDraft> {\n const draftState = this.#getDraftState();\n\n if (draftState.draftOpen) {\n throw new Error(\"Only one text stream draft can be open at a time\");\n }\n\n await this.#fileAccess.ensureDirectory(this.#getDirectoryPath());\n draftState.draftOpen = true;\n\n return new TextStreamDraft(this.#serialId, await this.#peekNextIndex(), {\n discard: () => {\n draftState.draftOpen = false;\n },\n finalize: async (startIndex, summary, sentences) =>\n await this.#commitDraft(startIndex, summary, sentences),\n });\n }\n\n public async getFragment(fragmentId: number): Promise<FragmentRecord> {\n const fragments = await this.#listFragments();\n const fragment = fragments.find((item) => item.fragmentId === fragmentId);\n\n if (fragment === undefined) {\n throw new Error(`Fragment ${fragmentId} does not exist`);\n }\n\n return fragment;\n }\n\n public async getSentence(sentenceIndex: number): Promise<SentenceRecord> {\n const location = await this.#getSentenceLocation(sentenceIndex);\n\n if (location === undefined) {\n throw new RangeError(`Sentence ${sentenceIndex} does not exist`);\n }\n\n return this.#readSentenceLocation(location, await this.#readContent());\n }\n\n public async listFragmentIds(): Promise<readonly number[]> {\n return (await this.#listFragments()).map((fragment) => fragment.fragmentId);\n }\n\n public async listSentences(): Promise<readonly SentenceRecord[]> {\n const rows = await this.#listSentenceLocations();\n const content = await this.#readContent();\n\n return rows.map((row) => this.#readSentenceLocation(row, content));\n }\n\n public async listSentencesInRange(\n startSentenceIndex: number,\n endSentenceIndex: number,\n ): Promise<readonly SentenceRecord[]> {\n if (endSentenceIndex < startSentenceIndex) {\n return [];\n }\n\n const rows = await this.#database.queryAll(\n `\n SELECT sentence_index, byte_offset, byte_length, words_count\n FROM text_sentence_records\n WHERE kind = ? AND chapter_id = ?\n AND sentence_index BETWEEN ? AND ?\n ORDER BY sentence_index\n `,\n [\n TEXT_STREAM_KIND[this.#stream],\n this.#serialId,\n startSentenceIndex,\n endSentenceIndex,\n ],\n mapTextSentenceLocation,\n );\n const content = await this.#readContent();\n\n return rows.map((row) => this.#readSentenceLocation(row, content));\n }\n\n public async readTextInRange(\n startSentenceIndex: number,\n endSentenceIndex: number,\n ): Promise<string | undefined> {\n if (endSentenceIndex < startSentenceIndex) {\n return \"\";\n }\n\n const rows = await this.#database.queryAll(\n `\n SELECT sentence_index, byte_offset, byte_length, words_count\n FROM text_sentence_records\n WHERE kind = ? AND chapter_id = ?\n AND sentence_index BETWEEN ? AND ?\n ORDER BY sentence_index\n `,\n [\n TEXT_STREAM_KIND[this.#stream],\n this.#serialId,\n startSentenceIndex,\n endSentenceIndex,\n ],\n mapTextSentenceLocation,\n );\n const first = rows[0];\n const last = rows[rows.length - 1];\n\n if (first === undefined || last === undefined) {\n return undefined;\n }\n\n const content = await this.#readContent();\n\n return content\n .subarray(first.byteOffset, last.byteOffset + last.byteLength)\n .toString(\"utf8\");\n }\n\n async #getSentenceLocation(\n sentenceIndex: number,\n ): Promise<TextSentenceLocation | undefined> {\n return await this.#database.queryOne(\n `\n SELECT sentence_index, byte_offset, byte_length, words_count\n FROM text_sentence_records\n WHERE kind = ? AND chapter_id = ? AND sentence_index = ?\n `,\n [TEXT_STREAM_KIND[this.#stream], this.#serialId, sentenceIndex],\n mapTextSentenceLocation,\n );\n }\n\n async #listSentenceLocations(): Promise<readonly TextSentenceLocation[]> {\n return await this.#database.queryAll(\n `\n SELECT sentence_index, byte_offset, byte_length, words_count\n FROM text_sentence_records\n WHERE kind = ? AND chapter_id = ?\n ORDER BY sentence_index\n `,\n [TEXT_STREAM_KIND[this.#stream], this.#serialId],\n mapTextSentenceLocation,\n );\n }\n\n #readSentenceLocation(\n location: TextSentenceLocation,\n content: Buffer,\n ): SentenceRecord {\n return new Sentence(\n content\n .subarray(\n location.byteOffset,\n location.byteOffset + location.byteLength,\n )\n .toString(\"utf8\"),\n location.wordsCount,\n );\n }\n\n public async readText(): Promise<string | undefined> {\n const content = await this.#fileAccess.readFile(this.#getTextPath());\n\n return content === undefined\n ? undefined\n : Buffer.from(content).toString(\"utf8\");\n }\n\n public async writeTextStream(\n text: string,\n options: WriteTextStreamOptions = {},\n ): Promise<void> {\n await this.delete();\n const sentences = await splitTextIntoSentenceSpans(text, options.segmenter);\n const draft = await this.createDraft();\n\n for (const sentence of sentences) {\n draft.addSentence(sentence.text, sentence.wordsCount, {\n byteOffset: sentence.byteOffset,\n byteLength: sentence.byteLength,\n });\n }\n\n await draft.commitWithText(text);\n }\n\n public async delete(): Promise<void> {\n await this.#fileAccess.deleteTree(this.#getTextPath());\n await this.#database.run(\n `\n DELETE FROM text_sentence_records\n WHERE kind = ? AND chapter_id = ?\n `,\n [TEXT_STREAM_KIND[this.#stream], this.#serialId],\n );\n delete this.#getDraftState().nextSentenceIndex;\n }\n\n public get path(): string {\n return this.#getTextPath();\n }\n\n public get serialId(): number {\n return this.#serialId;\n }\n\n async #commitDraft(\n startIndex: number,\n textOverride: string,\n sentences: readonly SentenceRecord[],\n ): Promise<FragmentRecord | undefined> {\n const draftState = this.#getDraftState();\n\n draftState.draftOpen = false;\n\n const existing = await this.#fileAccess.readFile(this.#getTextPath());\n const existingBuffer =\n existing === undefined ? Buffer.alloc(0) : Buffer.from(existing);\n const text =\n textOverride === \"\"\n ? sentences.map(getSentenceRawText).join(\"\")\n : textOverride;\n const appendBuffer = Buffer.from(text, \"utf8\");\n let offset = existingBuffer.length;\n\n await this.#fileAccess.ensureDirectory(this.#getDirectoryPath());\n await this.#fileAccess.writeFile(\n this.#getTextPath(),\n Buffer.concat([existingBuffer, appendBuffer]),\n { overwrite: true },\n );\n\n if (sentences.length === 0) {\n return undefined;\n }\n\n for (let index = 0; index < sentences.length; index += 1) {\n const sentence = sentences[index];\n\n if (sentence === undefined) {\n continue;\n }\n\n const length = getSentenceByteLength(sentence);\n const explicitOffset = getSentenceByteOffset(sentence);\n const sentenceOffset = offset + explicitOffset;\n\n await this.#database.run(\n `\n INSERT OR REPLACE INTO text_sentence_records (\n kind,\n chapter_id,\n sentence_index,\n words_count,\n byte_offset,\n byte_length\n )\n VALUES (?, ?, ?, ?, ?, ?)\n `,\n [\n TEXT_STREAM_KIND[this.#stream],\n this.#serialId,\n startIndex + index,\n sentence.wordsCount,\n sentenceOffset,\n length,\n ],\n );\n if (!hasSentenceByteOffset(sentence)) {\n offset += length;\n }\n }\n\n draftState.nextSentenceIndex = startIndex + sentences.length;\n\n return {\n fragmentId: startIndex,\n sentences,\n serialId: this.#serialId,\n summary: \"\",\n };\n }\n\n async #listFragments(): Promise<readonly FragmentRecord[]> {\n const sentences = await this.listSentences();\n const fragments: FragmentRecord[] = [];\n let current: SentenceRecord[] = [];\n let currentWords = 0;\n let fragmentStart = 0;\n\n for (let index = 0; index < sentences.length; index += 1) {\n const sentence = sentences[index];\n\n if (sentence === undefined) {\n continue;\n }\n if (\n current.length > 0 &&\n currentWords + sentence.wordsCount > DEFAULT_FRAGMENT_WORDS_COUNT\n ) {\n fragments.push({\n fragmentId: fragmentStart,\n sentences: current,\n serialId: this.#serialId,\n summary: \"\",\n });\n fragmentStart = index;\n current = [];\n currentWords = 0;\n }\n\n current.push(sentence);\n currentWords += sentence.wordsCount;\n }\n\n if (current.length > 0) {\n fragments.push({\n fragmentId: fragmentStart,\n sentences: current,\n serialId: this.#serialId,\n summary: \"\",\n });\n }\n\n return fragments;\n }\n\n async #peekNextIndex(): Promise<number> {\n const draftState = this.#getDraftState();\n\n if (draftState.nextSentenceIndex !== undefined) {\n return draftState.nextSentenceIndex;\n }\n\n draftState.nextSentenceIndex =\n (await this.#database.queryOne(\n `\n SELECT COALESCE(MAX(sentence_index), -1) + 1 AS next_index\n FROM text_sentence_records\n WHERE kind = ? AND chapter_id = ?\n `,\n [TEXT_STREAM_KIND[this.#stream], this.#serialId],\n (row) => Number(row.next_index),\n )) ?? 0;\n\n return draftState.nextSentenceIndex;\n }\n\n async #readContent(): Promise<Buffer> {\n const content = await this.#fileAccess.readFile(this.#getTextPath());\n\n return Buffer.from(content ?? new Uint8Array());\n }\n\n #getDirectoryPath(): string {\n return join(this.#documentPath, \"texts\", this.#stream);\n }\n\n #getTextPath(): string {\n return join(this.#getDirectoryPath(), `${this.#serialId}.txt`);\n }\n\n #getDraftState(): TextStreamDraftState {\n const key = `${this.#documentPath}\\0${this.#stream}\\0${this.#serialId}`;\n let state = SerialTextStream.#draftStates.get(key);\n\n if (state === undefined) {\n state = { draftOpen: false };\n SerialTextStream.#draftStates.set(key, state);\n }\n\n return state;\n }\n}\n\nfunction mapTextSentenceLocation(\n row: Record<string, unknown>,\n): TextSentenceLocation {\n return {\n byteLength: Number(row.byte_length),\n byteOffset: Number(row.byte_offset),\n sentenceIndex: Number(row.sentence_index),\n wordsCount: Number(row.words_count),\n };\n}\n\nexport class TextStreamDraft {\n #committed = false;\n readonly #discard: () => void;\n readonly #finalize: (\n startSentenceIndex: number,\n summary: string,\n sentences: readonly SentenceRecord[],\n ) => Promise<FragmentRecord | undefined>;\n readonly #sentences: SentenceRecord[] = [];\n readonly #serialId: number;\n readonly #startSentenceIndex: number;\n #summary = \"\";\n\n public constructor(\n serialId: number,\n startSentenceIndex: number,\n callbacks: {\n readonly discard: () => void;\n readonly finalize: (\n startSentenceIndex: number,\n summary: string,\n sentences: readonly SentenceRecord[],\n ) => Promise<FragmentRecord | undefined>;\n },\n ) {\n this.#discard = callbacks.discard;\n this.#finalize = callbacks.finalize;\n this.#serialId = serialId;\n this.#startSentenceIndex = startSentenceIndex;\n }\n\n public addSentence(\n text: string,\n wordsCount: number,\n location?: {\n readonly byteOffset: number;\n readonly byteLength: number;\n },\n ): SentenceId {\n this.#assertActive();\n const sentenceIndex = this.#startSentenceIndex + this.#sentences.length;\n const sentence = new Sentence(text, wordsCount);\n\n if (location !== undefined) {\n Object.assign(sentence, {\n byteLength: location.byteLength,\n byteOffset: location.byteOffset,\n });\n }\n\n this.#sentences.push(sentence);\n\n return [this.#serialId, sentenceIndex];\n }\n\n public async commit(): Promise<FragmentRecord | undefined> {\n this.#assertActive();\n this.#committed = true;\n\n return await this.#finalize(\n this.#startSentenceIndex,\n this.#summary,\n this.#sentences,\n );\n }\n\n public async commitWithText(\n text: string,\n ): Promise<FragmentRecord | undefined> {\n this.#assertActive();\n this.#committed = true;\n\n return await this.#finalize(\n this.#startSentenceIndex,\n text,\n this.#sentences,\n );\n }\n\n public discard(): void {\n this.#assertActive();\n this.#committed = true;\n this.#discard();\n }\n\n public setSummary(summary: string): void {\n this.#assertActive();\n this.#summary = summary;\n }\n\n public get fragmentId(): number {\n return this.#startSentenceIndex;\n }\n\n #assertActive(): void {\n if (this.#committed) {\n throw new Error(\"Text stream draft is already finalized\");\n }\n }\n}\n\nasync function splitTextIntoSentenceSpans(\n text: string,\n segmenter: TextStreamSentenceSegmenter | undefined,\n): Promise<\n ReadonlyArray<\n SentenceRecord & {\n readonly byteOffset: number;\n readonly byteLength: number;\n }\n >\n> {\n if (segmenter !== undefined) {\n return await splitTextIntoCustomSentenceSpans(text, segmenter);\n }\n\n const spans: Array<\n SentenceRecord & {\n readonly byteOffset: number;\n readonly byteLength: number;\n }\n > = [];\n\n for (const segment of createSentenceSegmenter().segment(text)) {\n const rawText = segment.segment;\n\n if (rawText.trim() === \"\") {\n continue;\n }\n const sentence = new Sentence(rawText, countWords(rawText));\n\n Object.assign(sentence, {\n byteLength: Buffer.byteLength(rawText, \"utf8\"),\n byteOffset: Buffer.byteLength(text.slice(0, segment.index), \"utf8\"),\n });\n spans.push(\n sentence as unknown as SentenceRecord & {\n readonly byteOffset: number;\n readonly byteLength: number;\n },\n );\n }\n\n return spans;\n}\n\nasync function splitTextIntoCustomSentenceSpans(\n text: string,\n segmenter: TextStreamSentenceSegmenter,\n): Promise<\n ReadonlyArray<\n SentenceRecord & {\n readonly byteOffset: number;\n readonly byteLength: number;\n }\n >\n> {\n const spans: Array<\n SentenceRecord & {\n readonly byteOffset: number;\n readonly byteLength: number;\n }\n > = [];\n\n for await (const segment of segmenter.pipe([text])) {\n const rawText = text.slice(\n segment.offset,\n segment.offset + segment.text.length,\n );\n\n if (rawText.trim() === \"\") {\n continue;\n }\n const sentence = new Sentence(rawText, segment.wordsCount);\n\n Object.assign(sentence, {\n byteLength: Buffer.byteLength(rawText, \"utf8\"),\n byteOffset: Buffer.byteLength(text.slice(0, segment.offset), \"utf8\"),\n });\n spans.push(\n sentence as unknown as SentenceRecord & {\n readonly byteOffset: number;\n readonly byteLength: number;\n },\n );\n }\n\n return spans;\n}\n\nlet SENTENCE_SEGMENTER: Intl.Segmenter | undefined;\n\nfunction createSentenceSegmenter(): Intl.Segmenter {\n SENTENCE_SEGMENTER ??= new Intl.Segmenter(undefined, {\n granularity: \"sentence\",\n });\n\n return SENTENCE_SEGMENTER;\n}\n\nfunction countWords(text: string): number {\n const trimmed = text.trim();\n\n return trimmed === \"\" ? 0 : trimmed.split(/\\s+/u).length;\n}\n\nfunction getSentenceByteOffset(sentence: SentenceRecord): number {\n const value = (sentence as { readonly byteOffset?: unknown }).byteOffset;\n\n return typeof value === \"number\" ? value : 0;\n}\n\nfunction hasSentenceByteOffset(sentence: SentenceRecord): boolean {\n return (\n typeof (sentence as { readonly byteOffset?: unknown }).byteOffset ===\n \"number\"\n );\n}\n\nfunction getSentenceByteLength(sentence: SentenceRecord): number {\n const value = (sentence as { readonly byteLength?: unknown }).byteLength;\n\n return typeof value === \"number\"\n ? value\n : Buffer.byteLength(getSentenceRawText(sentence), \"utf8\");\n}\n\nfunction getSentenceRawText(sentence: SentenceRecord): string {\n const value = (sentence as { readonly rawText?: unknown }).rawText;\n\n return typeof value === \"string\" ? value : sentence.text;\n}\n"],"mappings":"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","names":[]}
|