@graphty/graph-io 0.3.19 → 0.3.21
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/README.md +49 -4
- package/dist/chunks/{escape-CWExcecC.js → escape-B-tkk_Cl.js} +74 -16
- package/dist/chunks/escape-B-tkk_Cl.js.map +1 -0
- package/dist/chunks/{writer-DQiKgQJc.js → export-Bh60Dv-n.js} +5 -79
- package/dist/chunks/export-Bh60Dv-n.js.map +1 -0
- package/dist/chunks/{exporter-CbMZyVt-.js → exporter-BGrsWamJ.js} +7 -6
- package/dist/chunks/{exporter-CbMZyVt-.js.map → exporter-BGrsWamJ.js.map} +1 -1
- package/dist/chunks/exporter-DIeGJXAZ.js +834 -0
- package/dist/chunks/exporter-DIeGJXAZ.js.map +1 -0
- package/dist/chunks/{importer-BNFuV1-K.js → importer-BWY2FFc5.js} +28 -7
- package/dist/chunks/importer-BWY2FFc5.js.map +1 -0
- package/dist/chunks/importer-DD-xv9_Y.js +1471 -0
- package/dist/chunks/importer-DD-xv9_Y.js.map +1 -0
- package/dist/chunks/{importer-BAP4PrxR.js → importer-DET1tg6s.js} +30 -20
- package/dist/chunks/importer-DET1tg6s.js.map +1 -0
- package/dist/chunks/{importer-ByPGO-09.js → importer-DEcKhsmQ.js} +2 -2
- package/dist/chunks/{importer-ByPGO-09.js.map → importer-DEcKhsmQ.js.map} +1 -1
- package/dist/chunks/{importer-BW-Ft2ps.js → importer-DIrbbnAf.js} +6 -5
- package/dist/chunks/{importer-BW-Ft2ps.js.map → importer-DIrbbnAf.js.map} +1 -1
- package/dist/chunks/importer-D_e7e7LX.js +3055 -0
- package/dist/chunks/importer-D_e7e7LX.js.map +1 -0
- package/dist/chunks/{importer-Bm1_5vPS.js → importer-eUREhBGj.js} +11 -8
- package/dist/chunks/importer-eUREhBGj.js.map +1 -0
- package/dist/chunks/{importer-DOepkgnG.js → importer-vi3bSdtw.js} +4 -4
- package/dist/chunks/{importer-DOepkgnG.js.map → importer-vi3bSdtw.js.map} +1 -1
- package/dist/chunks/{importer-BVGtU1NA.js → importer-zGLo8Dg_.js} +6 -5
- package/dist/chunks/{importer-BVGtU1NA.js.map → importer-zGLo8Dg_.js.map} +1 -1
- package/dist/chunks/{json-elements-CZY1wiZh.js → json-elements-DDS8N2Dd.js} +2 -2
- package/dist/chunks/{json-elements-CZY1wiZh.js.map → json-elements-DDS8N2Dd.js.map} +1 -1
- package/dist/chunks/{records-BzNicMsf.js → records-dbRkxwaq.js} +2 -2
- package/dist/chunks/{records-BzNicMsf.js.map → records-dbRkxwaq.js.map} +1 -1
- package/dist/chunks/{report-BcWboivV.js → report-B1z4WT9e.js} +143 -111
- package/dist/chunks/{report-BcWboivV.js.map → report-B1z4WT9e.js.map} +1 -1
- package/dist/chunks/{weights-CwISIpCP.js → weights-Dzba96G3.js} +5 -5
- package/dist/chunks/{weights-CwISIpCP.js.map → weights-Dzba96G3.js.map} +1 -1
- package/dist/chunks/writer-C7flM-Ih.js +77 -0
- package/dist/chunks/writer-C7flM-Ih.js.map +1 -0
- package/dist/csv.js +6 -5
- package/dist/csv.js.map +1 -1
- package/dist/cx.js +1 -1
- package/dist/cx2.js +2 -2
- package/dist/cys.d.ts +1 -0
- package/dist/cys.js +6 -0
- package/dist/cys.js.map +1 -0
- package/dist/dot.js +1 -1
- package/dist/gexf.js +5 -4
- package/dist/gexf.js.map +1 -1
- package/dist/gml.js +12 -14
- package/dist/gml.js.map +1 -1
- package/dist/graph-io.js +288 -141
- package/dist/graph-io.js.map +1 -1
- package/dist/graphml.js +1 -1
- package/dist/json.js +1 -1
- package/dist/neo4j.js +6 -5
- package/dist/neo4j.js.map +1 -1
- package/dist/obo.js +1 -1
- package/dist/pajek.js +1 -1
- package/dist/src/common/cell-budget.d.ts +84 -0
- package/dist/src/common/cell-budget.d.ts.map +1 -0
- package/dist/src/common/cell-budget.js +138 -0
- package/dist/src/common/cell-budget.js.map +1 -0
- package/dist/src/common/input.d.ts +10 -0
- package/dist/src/common/input.d.ts.map +1 -1
- package/dist/src/common/input.js +39 -0
- package/dist/src/common/input.js.map +1 -1
- package/dist/src/common/options.d.ts +6 -0
- package/dist/src/common/options.d.ts.map +1 -1
- package/dist/src/common/options.js +1 -1
- package/dist/src/common/options.js.map +1 -1
- package/dist/src/common/xml.d.ts +37 -3
- package/dist/src/common/xml.d.ts.map +1 -1
- package/dist/src/common/xml.js +86 -6
- package/dist/src/common/xml.js.map +1 -1
- package/dist/src/common/zip.d.ts +92 -0
- package/dist/src/common/zip.d.ts.map +1 -0
- package/dist/src/common/zip.js +399 -0
- package/dist/src/common/zip.js.map +1 -0
- package/dist/src/formats/cx/importer.d.ts.map +1 -1
- package/dist/src/formats/cx/importer.js +26 -17
- package/dist/src/formats/cx/importer.js.map +1 -1
- package/dist/src/formats/cys/constants.d.ts +68 -0
- package/dist/src/formats/cys/constants.d.ts.map +1 -0
- package/dist/src/formats/cys/constants.js +76 -0
- package/dist/src/formats/cys/constants.js.map +1 -0
- package/dist/src/formats/cys/importer.d.ts +38 -0
- package/dist/src/formats/cys/importer.d.ts.map +1 -0
- package/dist/src/formats/cys/importer.js +830 -0
- package/dist/src/formats/cys/importer.js.map +1 -0
- package/dist/src/formats/cys/index.d.ts +7 -0
- package/dist/src/formats/cys/index.d.ts.map +1 -0
- package/dist/src/formats/cys/index.js +7 -0
- package/dist/src/formats/cys/index.js.map +1 -0
- package/dist/src/formats/cys/session.d.ts +132 -0
- package/dist/src/formats/cys/session.d.ts.map +1 -0
- package/dist/src/formats/cys/session.js +315 -0
- package/dist/src/formats/cys/session.js.map +1 -0
- package/dist/src/formats/cys/tables.d.ts +90 -0
- package/dist/src/formats/cys/tables.d.ts.map +1 -0
- package/dist/src/formats/cys/tables.js +293 -0
- package/dist/src/formats/cys/tables.js.map +1 -0
- package/dist/src/formats/dot/exporter.d.ts +2 -0
- package/dist/src/formats/dot/exporter.d.ts.map +1 -1
- package/dist/src/formats/dot/exporter.js +12 -0
- package/dist/src/formats/dot/exporter.js.map +1 -1
- package/dist/src/formats/dot/importer.js +6 -2
- package/dist/src/formats/dot/importer.js.map +1 -1
- package/dist/src/formats/gexf/importer.d.ts +2 -2
- package/dist/src/formats/gexf/importer.d.ts.map +1 -1
- package/dist/src/formats/gexf/importer.js +1 -1
- package/dist/src/formats/gexf/importer.js.map +1 -1
- package/dist/src/formats/gml/exporter.d.ts +0 -8
- package/dist/src/formats/gml/exporter.d.ts.map +1 -1
- package/dist/src/formats/gml/exporter.js +7 -17
- package/dist/src/formats/gml/exporter.js.map +1 -1
- package/dist/src/formats/json/exporter.d.ts.map +1 -1
- package/dist/src/formats/json/exporter.js +3 -1
- package/dist/src/formats/json/exporter.js.map +1 -1
- package/dist/src/formats/json/importer.d.ts.map +1 -1
- package/dist/src/formats/json/importer.js +3 -2
- package/dist/src/formats/json/importer.js.map +1 -1
- package/dist/src/formats/xgmml/columns.d.ts +152 -0
- package/dist/src/formats/xgmml/columns.d.ts.map +1 -0
- package/dist/src/formats/xgmml/columns.js +593 -0
- package/dist/src/formats/xgmml/columns.js.map +1 -0
- package/dist/src/formats/xgmml/constants.d.ts +196 -0
- package/dist/src/formats/xgmml/constants.d.ts.map +1 -0
- package/dist/src/formats/xgmml/constants.js +197 -0
- package/dist/src/formats/xgmml/constants.js.map +1 -0
- package/dist/src/formats/xgmml/document.d.ts +361 -0
- package/dist/src/formats/xgmml/document.d.ts.map +1 -0
- package/dist/src/formats/xgmml/document.js +695 -0
- package/dist/src/formats/xgmml/document.js.map +1 -0
- package/dist/src/formats/xgmml/emit.d.ts +341 -0
- package/dist/src/formats/xgmml/emit.d.ts.map +1 -0
- package/dist/src/formats/xgmml/emit.js +1275 -0
- package/dist/src/formats/xgmml/emit.js.map +1 -0
- package/dist/src/formats/xgmml/exporter.d.ts +24 -0
- package/dist/src/formats/xgmml/exporter.d.ts.map +1 -0
- package/dist/src/formats/xgmml/exporter.js +999 -0
- package/dist/src/formats/xgmml/exporter.js.map +1 -0
- package/dist/src/formats/xgmml/importer.d.ts +58 -0
- package/dist/src/formats/xgmml/importer.d.ts.map +1 -0
- package/dist/src/formats/xgmml/importer.js +360 -0
- package/dist/src/formats/xgmml/importer.js.map +1 -0
- package/dist/src/formats/xgmml/index.d.ts +8 -0
- package/dist/src/formats/xgmml/index.d.ts.map +1 -0
- package/dist/src/formats/xgmml/index.js +8 -0
- package/dist/src/formats/xgmml/index.js.map +1 -0
- package/dist/src/formats/xgmml/values.d.ts +60 -0
- package/dist/src/formats/xgmml/values.d.ts.map +1 -0
- package/dist/src/formats/xgmml/values.js +148 -0
- package/dist/src/formats/xgmml/values.js.map +1 -0
- package/dist/src/index.d.ts +2 -0
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +2 -0
- package/dist/src/index.js.map +1 -1
- package/dist/src/registry.d.ts +7 -0
- package/dist/src/registry.d.ts.map +1 -1
- package/dist/src/registry.js +25 -10
- package/dist/src/registry.js.map +1 -1
- package/dist/src/sniff.d.ts +1 -1
- package/dist/src/sniff.d.ts.map +1 -1
- package/dist/src/sniff.js +2 -0
- package/dist/src/sniff.js.map +1 -1
- package/dist/xgmml.d.ts +1 -0
- package/dist/xgmml.js +9 -0
- package/dist/xgmml.js.map +1 -0
- package/package.json +15 -2
- package/src/common/cell-budget.ts +170 -0
- package/src/common/input.ts +40 -0
- package/src/common/options.ts +1 -1
- package/src/common/xml.ts +127 -6
- package/src/common/zip.ts +472 -0
- package/src/formats/cx/importer.ts +27 -19
- package/src/formats/cys/constants.ts +99 -0
- package/src/formats/cys/importer.ts +1100 -0
- package/src/formats/cys/index.ts +7 -0
- package/src/formats/cys/session.ts +428 -0
- package/src/formats/cys/tables.ts +400 -0
- package/src/formats/dot/exporter.ts +17 -0
- package/src/formats/dot/importer.ts +6 -2
- package/src/formats/gexf/importer.ts +0 -1
- package/src/formats/gml/exporter.ts +7 -18
- package/src/formats/json/exporter.ts +3 -1
- package/src/formats/json/importer.ts +3 -2
- package/src/formats/xgmml/columns.ts +747 -0
- package/src/formats/xgmml/constants.ts +265 -0
- package/src/formats/xgmml/document.ts +975 -0
- package/src/formats/xgmml/emit.ts +1563 -0
- package/src/formats/xgmml/exporter.ts +1215 -0
- package/src/formats/xgmml/importer.ts +491 -0
- package/src/formats/xgmml/index.ts +8 -0
- package/src/formats/xgmml/values.ts +183 -0
- package/src/index.ts +9 -0
- package/src/registry.ts +41 -15
- package/src/sniff.ts +5 -1
- package/dist/chunks/escape-CWExcecC.js.map +0 -1
- package/dist/chunks/importer-BAP4PrxR.js.map +0 -1
- package/dist/chunks/importer-BNFuV1-K.js.map +0 -1
- package/dist/chunks/importer-Bm1_5vPS.js.map +0 -1
- package/dist/chunks/writer-DQiKgQJc.js.map +0 -1
package/dist/graph-io.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"graph-io.js","sources":["../src/registry.ts"],"sourcesContent":["/**\n * The importer / exporter registry (design sections 8.2 and 8.4): the eight built-in formats\n * registered by name, `sniff()` over them, and the two conveniences for callers who do not own a\n * sink: `importGraph()` sniffs the format, creates a builder seeded from the common options\n * (`directed: true` as a placeholder; the importer sets the real value), imports and freezes;\n * `exportGraph()` looks the exporter up by name. A caller who owns a builder uses the importer\n * objects directly (the subpath exports) and this module never touches their sink.\n */\n\nimport {\n type FreezeOptions,\n type FreezeReport,\n GraphBuilder,\n type GraphBuilderOptions,\n GraphFormatError,\n type GraphSnapshot,\n} from \"@graphty/graph-format\";\n\nimport { throwIfAborted } from \"./common/input.js\";\nimport { ImportReportBuilder } from \"./common/report.js\";\nimport { csvExporter, csvImporter } from \"./formats/csv/index.js\";\nimport { cxImporter } from \"./formats/cx/index.js\";\nimport { cx2Exporter, cx2Importer } from \"./formats/cx2/index.js\";\nimport { dotExporter, dotImporter } from \"./formats/dot/index.js\";\nimport { gexfExporter, gexfImporter } from \"./formats/gexf/index.js\";\nimport { gmlExporter, gmlImporter } from \"./formats/gml/index.js\";\nimport { graphmlExporter, graphmlImporter } from \"./formats/graphml/index.js\";\nimport { jsonExporter, jsonImporter } from \"./formats/json/index.js\";\nimport { neo4jExporter, neo4jImporter } from \"./formats/neo4j/index.js\";\nimport { oboImporter } from \"./formats/obo/index.js\";\nimport { pajekExporter, pajekImporter } from \"./formats/pajek/index.js\";\nimport { rankFormats, SNIFF_HEAD_BYTES, type SniffHints, type SniffResult } from \"./sniff.js\";\nimport {\n type CommonExportOptions,\n type CommonImportOptions,\n type GraphChoiceOptions,\n type GraphExporter,\n type GraphImporter,\n type GraphListing,\n type ImportInput,\n type ImportReport,\n type LossNote,\n} from \"./types.js\";\n\n/** The issue code of an input whose format no registered importer recognises. */\nexport const UNKNOWN_FORMAT_CODE = \"E_UNKNOWN_FORMAT\";\n\n/** The builder options importGraph() accepts beyond the ones the common import options seed. */\nexport type BuilderSeed = Omit<\n GraphBuilderOptions,\n \"directed\" | \"addMissingNodes\" | \"duplicateEdges\" | \"selfLoops\" | \"weightDtype\"\n>;\n\n/**\n * The options of importGraph(): the common import options (which also seed the registry's\n * builder, design section 8.4), the format choice and the hints sniffing uses, the builder and\n * freeze options, and any format-specific option (`delimiter`, `dialect`, ...) passed through to\n * the importer unchanged. `graphIndex` / `graphName` choose one graph of an input that holds\n * several, for the formats that list their graphs.\n */\nexport interface ImportGraphOptions extends CommonImportOptions, GraphChoiceOptions {\n /** The format name, or \"auto\" (default) to sniff it from the filename, MIME type and content. */\n readonly format?: string | undefined;\n /** The file name or path the input came from, a hint for sniffing. */\n readonly filename?: string | null | undefined;\n /** The MIME type the input was served as, a hint for sniffing. */\n readonly mimeType?: string | null | undefined;\n /** Builder options the common options do not cover (`weighted`, `expectedNodes`, ...). */\n readonly builder?: BuilderSeed | undefined;\n /** Options of the freeze that follows the import. */\n readonly freeze?: FreezeOptions | undefined;\n /** Format-specific options, passed to the importer as they are. */\n readonly [formatOption: string]: unknown;\n}\n\n/** What importGraph() returns (design section 8.4). */\nexport interface ImportGraphResult {\n /** The format the input was read as. */\n readonly format: string;\n /** The sniff that chose the importer, or null when the caller named the format. */\n readonly sniff: SniffResult | null;\n /** The frozen snapshot. */\n readonly snapshot: GraphSnapshot;\n /** The importer's report. */\n readonly report: ImportReport;\n /** The freeze report (design section 6.6). */\n readonly freeze: FreezeReport;\n}\n\n/** The options of exportGraph(): the common export options plus any format-specific option, passed through. */\nexport interface ExportGraphOptions extends CommonExportOptions {\n /** Format-specific options, passed to the exporter as they are. */\n readonly [formatOption: string]: unknown;\n}\n\n/** The keys of ImportGraphOptions that belong to the registry, never to an importer. */\nconst REGISTRY_KEYS: ReadonlySet<string> = new Set([\"format\", \"filename\", \"mimeType\", \"builder\", \"freeze\"]);\n\n/**\n * A registry of importers and exporters by format name. Registration order is the tie-break\n * order of sniffing (design section 8.2); the default registry lists the built-in formats in the\n * order of GRAPH_FORMATS.\n */\nexport class FormatRegistry {\n private readonly importerMap = new Map<string, GraphImporter>();\n\n private readonly exporterMap = new Map<string, GraphExporter>();\n\n /**\n * Register an importer under its format name, replacing one of the same name in place (the\n * original registration order is kept).\n * @param importer - the importer\n * @returns this registry, for chaining\n */\n registerImporter(importer: GraphImporter): this {\n this.importerMap.set(importer.format, importer);\n return this;\n }\n\n /**\n * Register an exporter under its format name, replacing one of the same name.\n * @param exporter - the exporter\n * @returns this registry, for chaining\n */\n registerExporter(exporter: GraphExporter): this {\n this.exporterMap.set(exporter.format, exporter);\n return this;\n }\n\n /**\n * The importer of a format.\n * @param format - the format name\n * @returns the importer; E_UNSUPPORTED when none is registered\n */\n importer(format: string): GraphImporter {\n const importer = this.importerMap.get(format);\n if (importer === undefined) {\n throw unknownFormat(\"importer\", format, this.importerMap.keys());\n }\n return importer;\n }\n\n /**\n * The exporter of a format.\n * @param format - the format name\n * @returns the exporter; E_UNSUPPORTED when none is registered\n */\n exporter(format: string): GraphExporter {\n const exporter = this.exporterMap.get(format);\n if (exporter === undefined) {\n throw unknownFormat(\"exporter\", format, this.exporterMap.keys());\n }\n return exporter;\n }\n\n /**\n * Whether an importer is registered for a format.\n * @param format - the format name\n * @returns true when importer(format) would succeed\n */\n hasImporter(format: string): boolean {\n return this.importerMap.has(format);\n }\n\n /**\n * Whether an exporter is registered for a format.\n * @param format - the format name\n * @returns true when exporter(format) would succeed\n */\n hasExporter(format: string): boolean {\n return this.exporterMap.has(format);\n }\n\n /**\n * Every registered importer, in registration order.\n * @returns the importers\n */\n importers(): readonly GraphImporter[] {\n return [...this.importerMap.values()];\n }\n\n /**\n * Every registered exporter, in registration order.\n * @returns the exporters\n */\n exporters(): readonly GraphExporter[] {\n return [...this.exporterMap.values()];\n }\n\n /**\n * The names of every format with an importer or an exporter, importers' order first.\n * @returns the format names, each once\n */\n formats(): readonly string[] {\n return [...new Set([...this.importerMap.keys(), ...this.exporterMap.keys()])];\n }\n\n /**\n * Rank the registered importers for an input (design section 8.2; the successor of\n * graphty-element's detectFormat()).\n * @param hints - the filename, MIME type and / or head of the input\n * @returns the candidates, best first; empty when nothing matches\n */\n sniffAll(hints: SniffHints): readonly SniffResult[] {\n return rankFormats(hints, this.importerMap.values());\n }\n\n /**\n * The best importer for an input, or null when no registered importer claims it.\n * @param hints - the filename, MIME type and / or head of the input\n * @returns the best candidate, or null\n */\n sniff(hints: SniffHints): SniffResult | null {\n const ranked = this.sniffAll(hints);\n return ranked.length > 0 ? ranked[0] : null;\n }\n\n /**\n * Read an input into a fresh builder and freeze it (design section 8.4: for callers who do not\n * own a sink). The format is the one named in the options, else sniffed from the filename,\n * the MIME type and the first bytes of the content; the builder is seeded from the common\n * options with `directed: true` as a placeholder that the importer overrides from the file.\n * An input holding several graphs yields the first, with a warning naming how many were\n * skipped; importAllGraphs() returns every one.\n * @param input - the text, bytes, stream or chunks to read\n * @param options - the format, hints, common and format-specific import options\n * @returns the snapshot, the import report and the freeze report\n */\n async importGraph(input: ImportInput, options: ImportGraphOptions = {}): Promise<ImportGraphResult> {\n const chosen = await this.choose(input, options);\n const builder = seededBuilder(options);\n let report: ImportReport;\n try {\n report = await chosen.importer.import(chosen.source, builder, importerOptions(options));\n } catch (err) {\n await chosen.peeked?.close();\n throw err;\n }\n return result(chosen, builder, report, options);\n }\n\n /**\n * Read every graph of an input (a DOT file with several graphs, a Pajek project with several\n * networks, a JGF document with a `graphs` array), each into its own fresh builder, frozen.\n * A format whose importer has no importAll() holds one graph per input, so the result has one\n * entry. Options, sniffing and the builder seed are those of importGraph().\n * @param input - the text, bytes, stream or chunks to read\n * @param options - the format, hints, common and format-specific import options\n * @returns one result per graph, in document order\n */\n async importAllGraphs(input: ImportInput, options: ImportGraphOptions = {}): Promise<ImportGraphResult[]> {\n const chosen = await this.choose(input, options);\n const { importer } = chosen;\n const builders: GraphBuilder[] = [];\n let reports: ImportReport[];\n try {\n if (importer.importAll === undefined) {\n builders.push(seededBuilder(options));\n reports = [await importer.import(chosen.source, builders[0], importerOptions(options))];\n } else {\n reports = await importer.importAll(\n chosen.source,\n () => {\n const builder = seededBuilder(options);\n builders.push(builder);\n return builder;\n },\n importerOptions(options),\n );\n }\n } catch (err) {\n await chosen.peeked?.close();\n throw err;\n }\n return reports.map((report, i) => result(chosen, builders[i], report, options));\n }\n\n /**\n * The graphs of an input that can hold several, without importing them (a Cytoscape session's\n * networks, a JGF `graphs` array), so a caller can offer a choice and then pass `graphIndex`\n * or `graphName` to importGraph(). The format is named or sniffed as by importGraph().\n * @param input - the text, bytes, stream or chunks to read\n * @param options - the format, hints, common and format-specific import options\n * @returns one listing per graph, in document order; null when the format's importer does not\n * list its graphs (importGraph() then reads the first)\n */\n async listGraphs(input: ImportInput, options: ImportGraphOptions = {}): Promise<readonly GraphListing[] | null> {\n const chosen = await this.choose(input, options);\n try {\n return chosen.importer.listGraphs === undefined\n ? null\n : await chosen.importer.listGraphs(chosen.source, importerOptions(options));\n } finally {\n await chosen.peeked?.close();\n }\n }\n\n /**\n * The importer for an input: the named format, or the sniffed one.\n * @param input - the input\n * @param options - the importGraph options\n * @returns the importer, the sniff, and the input to read (replayed for a stream)\n */\n private async choose(input: ImportInput, options: ImportGraphOptions): Promise<ChosenImporter> {\n const requested = options.format ?? \"auto\";\n if (requested !== \"auto\") {\n return { importer: this.importer(requested), sniff: null, source: input, peeked: null };\n }\n const peeked = await peekHead(input, SNIFF_HEAD_BYTES, options.signal ?? null);\n const sniff = this.sniff({ filename: options.filename, mimeType: options.mimeType, head: peeked.head });\n if (sniff === null) {\n const report = new ImportReportBuilder(\"unknown\", 0);\n return report.fail(\n UNKNOWN_FORMAT_CODE,\n `no registered importer recognises the input${describeHints(options)}; pass the format explicitly`,\n undefined,\n { formats: this.formats() },\n );\n }\n return { importer: this.importer(sniff.format), sniff, source: peeked.input, peeked };\n }\n\n /**\n * Write a snapshot in a format, as UTF-8 chunks (design section 8.5).\n * @param snapshot - the snapshot\n * @param format - the format name\n * @param options - the exporter's common and format-specific options\n * @returns the encoded chunks\n */\n exportGraph(snapshot: GraphSnapshot, format: string, options?: ExportGraphOptions): AsyncIterable<Uint8Array> {\n return this.exporter(format).export(snapshot, options);\n }\n\n /**\n * Write a snapshot in a format, as one string.\n * @param snapshot - the snapshot\n * @param format - the format name\n * @param options - the exporter's common and format-specific options\n * @returns the whole document\n */\n async exportGraphToString(snapshot: GraphSnapshot, format: string, options?: ExportGraphOptions): Promise<string> {\n return this.exporter(format).exportToString(snapshot, options);\n }\n\n /**\n * What exporting a snapshot in a format would lose, without writing anything.\n * @param snapshot - the snapshot\n * @param format - the format name\n * @param options - the exporter's common and format-specific options\n * @returns the loss notes, empty when the export is exact\n */\n checkExport(snapshot: GraphSnapshot, format: string, options?: ExportGraphOptions): readonly LossNote[] {\n return this.exporter(format).check(snapshot, options);\n }\n}\n\n/**\n * A registry holding the eight built-in importers and exporters in the order of GRAPH_FORMATS.\n * @returns a new registry\n */\nexport function createRegistry(): FormatRegistry {\n return new FormatRegistry()\n .registerImporter(jsonImporter)\n .registerExporter(jsonExporter)\n .registerImporter(graphmlImporter)\n .registerExporter(graphmlExporter)\n .registerImporter(gexfImporter)\n .registerExporter(gexfExporter)\n .registerImporter(csvImporter)\n .registerExporter(csvExporter)\n .registerImporter(gmlImporter)\n .registerExporter(gmlExporter)\n .registerImporter(dotImporter)\n .registerExporter(dotExporter)\n .registerImporter(pajekImporter)\n .registerExporter(pajekExporter)\n .registerImporter(neo4jImporter)\n .registerExporter(neo4jExporter)\n .registerImporter(cx2Importer)\n .registerExporter(cx2Exporter)\n .registerImporter(cxImporter)\n .registerImporter(oboImporter);\n}\n\n/** The default registry: every built-in format. */\nexport const registry: FormatRegistry = createRegistry();\n\n/**\n * Read an input into a fresh builder and freeze it, through the default registry (design section\n * 8.4: `importGraph(input, { format?, ...options })`).\n * @param input - the text, bytes, stream or chunks to read\n * @param options - the format, hints, common and format-specific import options\n * @returns the snapshot, the import report and the freeze report\n */\nexport function importGraph(input: ImportInput, options?: ImportGraphOptions): Promise<ImportGraphResult> {\n return registry.importGraph(input, options);\n}\n\n/**\n * Read every graph of an input, each into its own frozen snapshot, through the default registry.\n * @param input - the text, bytes, stream or chunks to read\n * @param options - the format, hints, common and format-specific import options\n * @returns one result per graph, in document order\n */\nexport function importAllGraphs(input: ImportInput, options?: ImportGraphOptions): Promise<ImportGraphResult[]> {\n return registry.importAllGraphs(input, options);\n}\n\n/**\n * The graphs of an input that can hold several, through the default registry.\n * @param input - the text, bytes, stream or chunks to read\n * @param options - the format, hints, common and format-specific import options\n * @returns one listing per graph, in document order; null when the format does not list its graphs\n */\nexport function listGraphs(input: ImportInput, options?: ImportGraphOptions): Promise<readonly GraphListing[] | null> {\n return registry.listGraphs(input, options);\n}\n\n/**\n * Write a snapshot in a format through the default registry, as UTF-8 chunks.\n * @param snapshot - the snapshot\n * @param format - the format name\n * @param options - the exporter's common and format-specific options\n * @returns the encoded chunks\n */\nexport function exportGraph(\n snapshot: GraphSnapshot,\n format: string,\n options?: ExportGraphOptions,\n): AsyncIterable<Uint8Array> {\n return registry.exportGraph(snapshot, format, options);\n}\n\n/**\n * Write a snapshot in a format through the default registry, as one string.\n * @param snapshot - the snapshot\n * @param format - the format name\n * @param options - the exporter's common and format-specific options\n * @returns the whole document\n */\nexport async function exportGraphToString(\n snapshot: GraphSnapshot,\n format: string,\n options?: ExportGraphOptions,\n): Promise<string> {\n return registry.exportGraphToString(snapshot, format, options);\n}\n\n/**\n * What exporting a snapshot in a format would lose, through the default registry.\n * @param snapshot - the snapshot\n * @param format - the format name\n * @param options - the exporter's common and format-specific options\n * @returns the loss notes, empty when the export is exact\n */\nexport function checkExport(\n snapshot: GraphSnapshot,\n format: string,\n options?: ExportGraphOptions,\n): readonly LossNote[] {\n return registry.checkExport(snapshot, format, options);\n}\n\n/**\n * Sniff an input's format through the default registry.\n * @param hints - the filename, MIME type and / or head of the input\n * @returns the best candidate, or null when no built-in importer claims it\n */\nexport function sniff(hints: SniffHints): SniffResult | null {\n return registry.sniff(hints);\n}\n\n/**\n * The options handed to the importer: everything but the registry's own keys.\n * @param options - the importGraph options\n * @returns the importer's options\n */\nfunction importerOptions(options: ImportGraphOptions): CommonImportOptions {\n const out: Record<string, unknown> = {};\n for (const [key, value] of Object.entries(options)) {\n if (!REGISTRY_KEYS.has(key)) {\n out[key] = value;\n }\n }\n return out;\n}\n\n/** The importer chosen for an input, and the input to hand it. */\ninterface ChosenImporter {\n /** The importer. */\n readonly importer: GraphImporter;\n /** The sniff that chose it, or null when the caller named the format. */\n readonly sniff: SniffResult | null;\n /** The input to read: the original, or a replaying iterable for a peeked stream. */\n readonly source: ImportInput;\n /** The peeked head of a sniffed input, or null. */\n readonly peeked: PeekedInput | null;\n}\n\n/**\n * A fresh builder seeded from the common options, `directed: true` as a placeholder the importer\n * overrides from the file.\n * @param options - the importGraph options\n * @returns the builder\n */\nfunction seededBuilder(options: ImportGraphOptions): GraphBuilder {\n return new GraphBuilder({\n weightDtype: options.weightDtype ?? \"f64\",\n ...options.builder,\n directed: true,\n addMissingNodes: options.addMissingNodes ?? true,\n duplicateEdges: options.duplicateEdges ?? \"keep\",\n selfLoops: options.selfLoops ?? \"keep\",\n });\n}\n\n/**\n * Freeze an imported builder into an importGraph result.\n * @param chosen - the importer and its sniff\n * @param builder - the filled builder\n * @param report - the importer's report\n * @param options - the importGraph options\n * @returns the frozen result\n */\nfunction result(\n chosen: ChosenImporter,\n builder: GraphBuilder,\n report: ImportReport,\n options: ImportGraphOptions,\n): ImportGraphResult {\n const frozen = builder.freezeWithReport(options.freeze);\n return Object.freeze({\n format: chosen.importer.format,\n sniff: chosen.sniff,\n snapshot: frozen.snapshot,\n report,\n freeze: frozen.report,\n });\n}\n\n/**\n * The E_UNSUPPORTED error of a format name nothing is registered under.\n * @param kind - importer or exporter\n * @param format - the requested name\n * @param known - the registered names\n * @returns the error\n */\nfunction unknownFormat(kind: \"importer\" | \"exporter\", format: string, known: Iterable<string>): GraphFormatError {\n const supported = [...known];\n return new GraphFormatError(\n \"E_UNSUPPORTED\",\n `no ${kind} is registered for format ${JSON.stringify(format)}; known: ${supported.join(\", \")}`,\n { option: \"format\", found: format, supported },\n );\n}\n\n/**\n * The hints of an import, for the unknown-format message.\n * @param options - the importGraph options\n * @returns \" (filename ..., MIME type ...)\" or an empty string\n */\nfunction describeHints(options: ImportGraphOptions): string {\n const parts: string[] = [];\n if (typeof options.filename === \"string\" && options.filename.length > 0) {\n parts.push(`filename ${JSON.stringify(options.filename)}`);\n }\n if (typeof options.mimeType === \"string\" && options.mimeType.length > 0) {\n parts.push(`MIME type ${JSON.stringify(options.mimeType)}`);\n }\n return parts.length === 0 ? \"\" : ` (${parts.join(\", \")})`;\n}\n\n/** A head read from an input, and the input to hand the importer (the same bytes, replayed for a stream). */\ninterface PeekedInput {\n /** The first bytes (or, for a text input, characters) of the content. */\n readonly head: Uint8Array | string;\n /** The input to read: the original for in-memory input, a replaying iterable for a stream. */\n readonly input: ImportInput;\n /**\n * Close the source when the importer never iterated the replaying input (it threw first, an\n * abort for instance): a stream's reader is cancelled and released, an async generator finalised.\n * @returns when the source is closed\n */\n close(): Promise<void>;\n}\n\n/**\n * The first `bytes` of an input without consuming it: in-memory input is sliced; a stream or an\n * async iterable is read until enough is buffered and then replayed (the buffered chunks first,\n * the rest as it arrives) through a new async iterable that cancels the source when the importer\n * stops early.\n * @param input - the input\n * @param bytes - how much to peek\n * @param signal - the cancellation signal, or null\n * @returns the head and the input to read\n */\nasync function peekHead(input: ImportInput, bytes: number, signal: AbortSignal | null): Promise<PeekedInput> {\n if (typeof input === \"string\") {\n return { head: input.slice(0, bytes), input, close: (): Promise<void> => Promise.resolve() };\n }\n if (input instanceof Uint8Array) {\n return { head: input.subarray(0, bytes), input, close: (): Promise<void> => Promise.resolve() };\n }\n throwIfAborted(signal);\n const source: AsyncIterator<string | Uint8Array> =\n typeof (input as { getReader?: unknown }).getReader === \"function\"\n ? readerIterator(input as ReadableStream<Uint8Array>)\n : (input as AsyncIterable<string | Uint8Array>)[Symbol.asyncIterator]();\n const buffered: (string | Uint8Array)[] = [];\n let size = 0;\n let finished = false;\n while (size < bytes) {\n if (signal !== null && signal.aborted) {\n await source.return?.();\n throwIfAborted(signal);\n }\n const next = await source.next();\n if (next.done === true) {\n finished = true;\n break;\n }\n buffered.push(next.value);\n size += typeof next.value === \"string\" ? next.value.length : next.value.byteLength;\n }\n if (!finished && signal !== null && signal.aborted) {\n // an abort that landed on the read completing the head: close the source before rethrowing\n await source.return?.();\n throwIfAborted(signal);\n }\n const replayed = replay(buffered, source, finished);\n return { head: joinHead(buffered, bytes), input: replayed, close: (): Promise<void> => replayed.close() };\n}\n\n/**\n * The head text or bytes of the buffered chunks: bytes when every chunk is bytes, text otherwise\n * (byte chunks decoded leniently; the importer decodes the real input strictly).\n * @param chunks - the buffered chunks\n * @param bytes - the head size\n * @returns the head\n */\nfunction joinHead(chunks: readonly (string | Uint8Array)[], bytes: number): Uint8Array | string {\n if (chunks.every((c) => c instanceof Uint8Array)) {\n const total = Math.min(\n bytes,\n chunks.reduce((sum, c) => sum + c.byteLength, 0),\n );\n const head = new Uint8Array(total);\n let offset = 0;\n for (const chunk of chunks) {\n if (offset >= total) {\n break;\n }\n const part = chunk.subarray(0, Math.min(chunk.byteLength, total - offset));\n head.set(part, offset);\n offset += part.byteLength;\n }\n return head;\n }\n const decoder = new TextDecoder(\"utf-8\", { fatal: false });\n let text = \"\";\n for (const chunk of chunks) {\n text += typeof chunk === \"string\" ? chunk : decoder.decode(chunk, { stream: true });\n if (text.length >= bytes) {\n break;\n }\n }\n return text.slice(0, bytes);\n}\n\n/**\n * An async iterable that yields the buffered chunks, then the rest of the source; the source is\n * closed when the consumer stops early.\n * @param buffered - the chunks already read\n * @param source - the iterator positioned after them\n * @param finished - whether the source is already exhausted\n * @returns the replaying iterable\n */\nfunction replay(\n buffered: readonly (string | Uint8Array)[],\n source: AsyncIterator<string | Uint8Array>,\n finished: boolean,\n): AsyncIterable<string | Uint8Array> & { close(): Promise<void> } {\n let exhausted = finished;\n const close = async (): Promise<void> => {\n if (!exhausted) {\n exhausted = true;\n await source.return?.();\n }\n };\n return {\n close,\n [Symbol.asyncIterator](): AsyncIterator<string | Uint8Array> {\n let position = 0;\n return {\n async next(): Promise<IteratorResult<string | Uint8Array>> {\n if (position < buffered.length) {\n return { done: false, value: buffered[position++] };\n }\n if (exhausted) {\n return { done: true, value: undefined };\n }\n const next = await source.next();\n if (next.done === true) {\n exhausted = true;\n return { done: true, value: undefined };\n }\n return next;\n },\n async return(): Promise<IteratorResult<string | Uint8Array>> {\n await close();\n return { done: true, value: undefined };\n },\n };\n },\n };\n}\n\n/**\n * An async iterator over a ReadableStream's chunks that cancels the stream when closed early.\n * @param stream - the stream\n * @returns the iterator\n */\nfunction readerIterator(stream: ReadableStream<Uint8Array>): AsyncIterator<Uint8Array> {\n const reader = stream.getReader();\n let done = false;\n return {\n async next(): Promise<IteratorResult<Uint8Array>> {\n if (done) {\n return { done: true, value: undefined };\n }\n const result = await reader.read();\n if (result.done) {\n done = true;\n reader.releaseLock();\n return { done: true, value: undefined };\n }\n return { done: false, value: result.value };\n },\n async return(): Promise<IteratorResult<Uint8Array>> {\n if (!done) {\n done = true;\n await reader.cancel().catch(() => undefined);\n reader.releaseLock();\n }\n return { done: true, value: undefined };\n },\n };\n}\n"],"names":["i","sniff","c","result"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"graph-io.js","sources":["../src/common/cell-budget.ts","../src/registry.ts"],"sourcesContent":["/**\n * A memory guard for the builder importGraph() fills. graph-format stores every attribute as a dense\n * column, one slot per node (or edge) whether or not that element has a value, so a file whose nodes\n * each carry a differently named attribute holds n values but allocates n x n slots: a few hundred\n * kilobytes of input can need gigabytes. The guard counts the slots that hold no value and stops the\n * import once they pass a limit. A dense file has almost no empty slots, so it is never stopped\n * however large it is.\n */\n\nimport {\n type ColumnDecl,\n type ColumnHandle,\n GraphBuilder,\n type GraphBuilderOptions,\n GraphFormatError,\n type NodeId,\n} from \"@graphty/graph-format\";\n\nimport { describe } from \"./options.js\";\nimport { ImportReportBuilder } from \"./report.js\";\n\n/** The issue code of an import stopped for allocating too many empty attribute slots. */\nexport const TOO_MANY_EMPTY_CELLS_CODE = \"E_TOO_MANY_EMPTY_CELLS\";\n\n/** The default limit: 2^24 empty slots, about 130 MB of f64 columns. */\nconst DEFAULT_MAX_EMPTY_CELLS = 2 ** 24;\n\n/**\n * Resolve the maxEmptyCells option.\n * @param value - the caller's value\n * @returns a non-negative integer or Infinity\n * @throws GraphFormatError E_UNSUPPORTED for anything else\n */\nexport function maxEmptyCellsOption(value: unknown): number {\n if (value === undefined) {\n return DEFAULT_MAX_EMPTY_CELLS;\n }\n if (typeof value === \"number\" && value >= 0 && (Number.isInteger(value) || value === Infinity)) {\n return value;\n }\n throw new GraphFormatError(\n \"E_UNSUPPORTED\",\n `option maxEmptyCells: ${describe(value)} is not a non-negative integer or Infinity`,\n { option: \"maxEmptyCells\", found: value },\n );\n}\n\n/** A GraphBuilder that throws an ImportError once its attribute columns hold too many empty slots. */\nexport class CellBudgetBuilder extends GraphBuilder {\n private readonly nodeColumns = new Set<number>();\n private readonly edgeColumns = new Set<number>();\n private values = 0;\n\n /**\n * Create a builder with a limit.\n * @param options - the builder options\n * @param format - the format being read, for the error's report\n * @param maxEmptyCells - the most empty slots allowed\n */\n constructor(\n options: GraphBuilderOptions,\n private readonly format: string,\n private readonly maxEmptyCells: number,\n ) {\n super(options);\n }\n\n /**\n * Add a node, then check the limit (its row adds a slot to every node column).\n * @param id - the node id\n * @returns the node index\n */\n override addNode(id: NodeId): number {\n const index = super.addNode(id);\n this.checkBudget();\n return index;\n }\n\n /**\n * Add an edge, then check the limit (its row adds a slot to every edge column).\n * @param source - source id\n * @param target - target id\n * @param weight - the weight\n * @returns the edge index\n */\n override addEdge(source: NodeId, target: NodeId, weight?: number): number {\n const edge = super.addEdge(source, target, weight);\n this.checkBudget();\n return edge;\n }\n\n /**\n * Declare a node column, then check the limit.\n * @param decl - the declaration\n * @returns the column handle\n */\n override declareNodeColumn(decl: ColumnDecl): ColumnHandle {\n const handle = super.declareNodeColumn(decl);\n this.nodeColumns.add(handle);\n this.checkBudget();\n return handle;\n }\n\n /**\n * Declare an edge column, then check the limit.\n * @param decl - the declaration\n * @returns the column handle\n */\n override declareEdgeColumn(decl: ColumnDecl): ColumnHandle {\n const handle = super.declareEdgeColumn(decl);\n this.edgeColumns.add(handle);\n this.checkBudget();\n return handle;\n }\n\n /**\n * Set a node cell (a new name declares a column), then check the limit.\n * @param column - the handle or name\n * @param index - the node index\n * @param value - the value\n */\n override setNodeValue(column: ColumnHandle | string, index: number, value: unknown): void {\n super.setNodeValue(column, index, value);\n this.nodeColumns.add(typeof column === \"string\" ? this.nodeColumn(column) : column);\n this.count(value);\n }\n\n /**\n * Set an edge cell (a new name declares a column), then check the limit.\n * @param column - the handle or name\n * @param edge - the edge index\n * @param value - the value\n */\n override setEdgeValue(column: ColumnHandle | string, edge: number, value: unknown): void {\n super.setEdgeValue(column, edge, value);\n this.edgeColumns.add(typeof column === \"string\" ? this.edgeColumn(column) : column);\n this.count(value);\n }\n\n /**\n * Count a written value and check the budget.\n * @param value - the value; null and undefined unset a slot and do not count\n */\n private count(value: unknown): void {\n if (value !== null && value !== undefined) {\n this.values++;\n }\n this.checkBudget();\n }\n\n /**\n * Throw when the columns' slots minus the values written pass the limit.\n * @throws ImportError E_TOO_MANY_EMPTY_CELLS\n */\n private checkBudget(): void {\n const slots = this.nodeColumns.size * this.nodeBound + this.edgeColumns.size * this.edgeBound;\n const empty = slots - this.values;\n if (empty > this.maxEmptyCells) {\n new ImportReportBuilder(this.format, Infinity).fail(\n TOO_MANY_EMPTY_CELLS_CODE,\n `the attributes are too sparse: ${this.nodeColumns.size} node and ${this.edgeColumns.size} edge ` +\n `attribute column(s) over ${this.nodeBound} node(s) and ${this.edgeBound} edge(s) would ` +\n `allocate more than ${this.maxEmptyCells} slots that hold no value; pass a larger ` +\n `maxEmptyCells (or Infinity) to read the file anyway`,\n undefined,\n { emptyCells: empty, maxEmptyCells: this.maxEmptyCells },\n );\n }\n }\n}\n","/**\n * The importer / exporter registry (design sections 8.2 and 8.4): the eight built-in formats\n * registered by name, `sniff()` over them, and the two conveniences for callers who do not own a\n * sink: `importGraph()` sniffs the format, creates a builder seeded from the common options\n * (`directed: true` as a placeholder; the importer sets the real value), imports and freezes;\n * `exportGraph()` looks the exporter up by name. A caller who owns a builder uses the importer\n * objects directly (the subpath exports) and this module never touches their sink.\n */\n\nimport {\n type FreezeOptions,\n type FreezeReport,\n GraphBuilder,\n type GraphBuilderOptions,\n GraphFormatError,\n type GraphSnapshot,\n} from \"@graphty/graph-format\";\n\nimport { CellBudgetBuilder, maxEmptyCellsOption } from \"./common/cell-budget.js\";\nimport { throwIfAborted } from \"./common/input.js\";\nimport { ImportReportBuilder } from \"./common/report.js\";\nimport { csvExporter, csvImporter } from \"./formats/csv/index.js\";\nimport { cxImporter } from \"./formats/cx/index.js\";\nimport { cx2Exporter, cx2Importer } from \"./formats/cx2/index.js\";\nimport { cysImporter } from \"./formats/cys/index.js\";\nimport { dotExporter, dotImporter } from \"./formats/dot/index.js\";\nimport { gexfExporter, gexfImporter } from \"./formats/gexf/index.js\";\nimport { gmlExporter, gmlImporter } from \"./formats/gml/index.js\";\nimport { graphmlExporter, graphmlImporter } from \"./formats/graphml/index.js\";\nimport { jsonExporter, jsonImporter } from \"./formats/json/index.js\";\nimport { neo4jExporter, neo4jImporter } from \"./formats/neo4j/index.js\";\nimport { oboImporter } from \"./formats/obo/index.js\";\nimport { pajekExporter, pajekImporter } from \"./formats/pajek/index.js\";\nimport { xgmmlExporter, xgmmlImporter } from \"./formats/xgmml/index.js\";\nimport { rankFormats, SNIFF_HEAD_BYTES, type SniffHints, type SniffResult } from \"./sniff.js\";\nimport {\n type CommonExportOptions,\n type CommonImportOptions,\n type GraphChoiceOptions,\n type GraphExporter,\n type GraphImporter,\n type GraphListing,\n type ImportInput,\n type ImportReport,\n type LossNote,\n} from \"./types.js\";\n\n/** The issue code of an input whose format no registered importer recognises. */\nexport const UNKNOWN_FORMAT_CODE = \"E_UNKNOWN_FORMAT\";\n\n/** The builder options importGraph() accepts beyond the ones the common import options seed. */\nexport type BuilderSeed = Omit<\n GraphBuilderOptions,\n \"directed\" | \"addMissingNodes\" | \"duplicateEdges\" | \"selfLoops\" | \"weightDtype\"\n>;\n\n/**\n * The options of importGraph(): the common import options (which also seed the registry's\n * builder, design section 8.4), the format choice and the hints sniffing uses, the builder and\n * freeze options, and any format-specific option (`delimiter`, `dialect`, ...) passed through to\n * the importer unchanged. `graphIndex` / `graphName` choose one graph of an input that holds\n * several, for the formats that list their graphs.\n */\nexport interface ImportGraphOptions extends CommonImportOptions, GraphChoiceOptions {\n /** The format name, or \"auto\" (default) to sniff it from the filename, MIME type and content. */\n readonly format?: string | undefined;\n /** The file name or path the input came from, a hint for sniffing. */\n readonly filename?: string | null | undefined;\n /** The MIME type the input was served as, a hint for sniffing. */\n readonly mimeType?: string | null | undefined;\n /** Builder options the common options do not cover (`weighted`, `expectedNodes`, ...). */\n readonly builder?: BuilderSeed | undefined;\n /** Options of the freeze that follows the import. */\n readonly freeze?: FreezeOptions | undefined;\n /**\n * The most attribute slots that hold no value the import may allocate before it stops with\n * E_TOO_MANY_EMPTY_CELLS. Every attribute is a column with one slot per node (or edge), so a file\n * whose nodes each have a differently named attribute would otherwise need nodes x attributes\n * memory. Default 2^24 (16,777,216); Infinity turns the check off. Dense files are never stopped.\n */\n readonly maxEmptyCells?: number | undefined;\n /** Format-specific options, passed to the importer as they are. */\n readonly [formatOption: string]: unknown;\n}\n\n/** What importGraph() returns (design section 8.4). */\nexport interface ImportGraphResult {\n /** The format the input was read as. */\n readonly format: string;\n /** The sniff that chose the importer, or null when the caller named the format. */\n readonly sniff: SniffResult | null;\n /** The frozen snapshot. */\n readonly snapshot: GraphSnapshot;\n /** The importer's report. */\n readonly report: ImportReport;\n /** The freeze report (design section 6.6). */\n readonly freeze: FreezeReport;\n}\n\n/** The options of exportGraph(): the common export options plus any format-specific option, passed through. */\nexport interface ExportGraphOptions extends CommonExportOptions {\n /** Format-specific options, passed to the exporter as they are. */\n readonly [formatOption: string]: unknown;\n}\n\n/** The keys of ImportGraphOptions that belong to the registry, never to an importer. */\nconst REGISTRY_KEYS: ReadonlySet<string> = new Set([\n \"format\",\n \"filename\",\n \"mimeType\",\n \"builder\",\n \"freeze\",\n \"maxEmptyCells\",\n]);\n\n/**\n * A registry of importers and exporters by format name. Registration order is the tie-break\n * order of sniffing (design section 8.2); the default registry lists the built-in formats in the\n * order of GRAPH_FORMATS.\n */\nexport class FormatRegistry {\n private readonly importerMap = new Map<string, GraphImporter>();\n\n private readonly exporterMap = new Map<string, GraphExporter>();\n\n /**\n * Register an importer under its format name, replacing one of the same name in place (the\n * original registration order is kept).\n * @param importer - the importer\n * @returns this registry, for chaining\n */\n registerImporter(importer: GraphImporter): this {\n this.importerMap.set(importer.format, importer);\n return this;\n }\n\n /**\n * Register an exporter under its format name, replacing one of the same name.\n * @param exporter - the exporter\n * @returns this registry, for chaining\n */\n registerExporter(exporter: GraphExporter): this {\n this.exporterMap.set(exporter.format, exporter);\n return this;\n }\n\n /**\n * The importer of a format.\n * @param format - the format name\n * @returns the importer; E_UNSUPPORTED when none is registered\n */\n importer(format: string): GraphImporter {\n const importer = this.importerMap.get(format);\n if (importer === undefined) {\n throw unknownFormat(\"importer\", format, this.importerMap.keys());\n }\n return importer;\n }\n\n /**\n * The exporter of a format.\n * @param format - the format name\n * @returns the exporter; E_UNSUPPORTED when none is registered\n */\n exporter(format: string): GraphExporter {\n const exporter = this.exporterMap.get(format);\n if (exporter === undefined) {\n throw unknownFormat(\"exporter\", format, this.exporterMap.keys());\n }\n return exporter;\n }\n\n /**\n * Whether an importer is registered for a format.\n * @param format - the format name\n * @returns true when importer(format) would succeed\n */\n hasImporter(format: string): boolean {\n return this.importerMap.has(format);\n }\n\n /**\n * Whether an exporter is registered for a format.\n * @param format - the format name\n * @returns true when exporter(format) would succeed\n */\n hasExporter(format: string): boolean {\n return this.exporterMap.has(format);\n }\n\n /**\n * Every registered importer, in registration order.\n * @returns the importers\n */\n importers(): readonly GraphImporter[] {\n return [...this.importerMap.values()];\n }\n\n /**\n * Every registered exporter, in registration order.\n * @returns the exporters\n */\n exporters(): readonly GraphExporter[] {\n return [...this.exporterMap.values()];\n }\n\n /**\n * The names of every format with an importer or an exporter, importers' order first.\n * @returns the format names, each once\n */\n formats(): readonly string[] {\n return [...new Set([...this.importerMap.keys(), ...this.exporterMap.keys()])];\n }\n\n /**\n * Rank the registered importers for an input (design section 8.2; the successor of\n * graphty-element's detectFormat()).\n * @param hints - the filename, MIME type and / or head of the input\n * @returns the candidates, best first; empty when nothing matches\n */\n sniffAll(hints: SniffHints): readonly SniffResult[] {\n return rankFormats(hints, this.importerMap.values());\n }\n\n /**\n * The best importer for an input, or null when no registered importer claims it.\n * @param hints - the filename, MIME type and / or head of the input\n * @returns the best candidate, or null\n */\n sniff(hints: SniffHints): SniffResult | null {\n const ranked = this.sniffAll(hints);\n return ranked.length > 0 ? ranked[0] : null;\n }\n\n /**\n * Read an input into a fresh builder and freeze it (design section 8.4: for callers who do not\n * own a sink). The format is the one named in the options, else sniffed from the filename,\n * the MIME type and the first bytes of the content; the builder is seeded from the common\n * options with `directed: true` as a placeholder that the importer overrides from the file.\n * An input holding several graphs yields the first, with a warning naming how many were\n * skipped; importAllGraphs() returns every one.\n * @param input - the text, bytes, stream or chunks to read\n * @param options - the format, hints, common and format-specific import options\n * @returns the snapshot, the import report and the freeze report\n */\n async importGraph(input: ImportInput, options: ImportGraphOptions = {}): Promise<ImportGraphResult> {\n const chosen = await this.choose(input, options);\n const builder = seededBuilder(options, chosen.importer.format);\n let report: ImportReport;\n try {\n report = await chosen.importer.import(chosen.source, builder, importerOptions(options));\n } catch (err) {\n await chosen.peeked?.close();\n throw err;\n }\n return result(chosen, builder, report, options);\n }\n\n /**\n * Read every graph of an input (a DOT file with several graphs, a Pajek project with several\n * networks, a JGF document with a `graphs` array), each into its own fresh builder, frozen.\n * A format whose importer has no importAll() holds one graph per input, so the result has one\n * entry. Options, sniffing and the builder seed are those of importGraph().\n * @param input - the text, bytes, stream or chunks to read\n * @param options - the format, hints, common and format-specific import options\n * @returns one result per graph, in document order\n */\n async importAllGraphs(input: ImportInput, options: ImportGraphOptions = {}): Promise<ImportGraphResult[]> {\n const chosen = await this.choose(input, options);\n const { importer } = chosen;\n const builders: GraphBuilder[] = [];\n let reports: ImportReport[];\n try {\n if (importer.importAll === undefined) {\n builders.push(seededBuilder(options, importer.format));\n reports = [await importer.import(chosen.source, builders[0], importerOptions(options))];\n } else {\n reports = await importer.importAll(\n chosen.source,\n () => {\n const builder = seededBuilder(options, importer.format);\n builders.push(builder);\n return builder;\n },\n importerOptions(options),\n );\n }\n } catch (err) {\n await chosen.peeked?.close();\n throw err;\n }\n return reports.map((report, i) => result(chosen, builders[i], report, options));\n }\n\n /**\n * The graphs of an input that can hold several, without importing them (a Cytoscape session's\n * networks, a JGF `graphs` array), so a caller can offer a choice and then pass `graphIndex`\n * or `graphName` to importGraph(). The format is named or sniffed as by importGraph().\n * @param input - the text, bytes, stream or chunks to read\n * @param options - the format, hints, common and format-specific import options\n * @returns one listing per graph, in document order; null when the format's importer does not\n * list its graphs (importGraph() then reads the first)\n */\n async listGraphs(input: ImportInput, options: ImportGraphOptions = {}): Promise<readonly GraphListing[] | null> {\n const chosen = await this.choose(input, options);\n try {\n return chosen.importer.listGraphs === undefined\n ? null\n : await chosen.importer.listGraphs(chosen.source, importerOptions(options));\n } finally {\n await chosen.peeked?.close();\n }\n }\n\n /**\n * The importer for an input: the named format, or the sniffed one.\n * @param input - the input\n * @param options - the importGraph options\n * @returns the importer, the sniff, and the input to read (replayed for a stream)\n */\n private async choose(input: ImportInput, options: ImportGraphOptions): Promise<ChosenImporter> {\n const requested = options.format ?? \"auto\";\n if (requested !== \"auto\") {\n return { importer: this.importer(requested), sniff: null, source: input, peeked: null };\n }\n const peeked = await peekHead(input, SNIFF_HEAD_BYTES, options.signal ?? null);\n const sniff = this.sniff({ filename: options.filename, mimeType: options.mimeType, head: peeked.head });\n if (sniff === null) {\n const report = new ImportReportBuilder(\"unknown\", 0);\n return report.fail(\n UNKNOWN_FORMAT_CODE,\n `no registered importer recognises the input${describeHints(options)}; pass the format explicitly`,\n undefined,\n { formats: this.formats() },\n );\n }\n return { importer: this.importer(sniff.format), sniff, source: peeked.input, peeked };\n }\n\n /**\n * Write a snapshot in a format, as UTF-8 chunks (design section 8.5).\n * @param snapshot - the snapshot\n * @param format - the format name\n * @param options - the exporter's common and format-specific options\n * @returns the encoded chunks\n */\n exportGraph(snapshot: GraphSnapshot, format: string, options?: ExportGraphOptions): AsyncIterable<Uint8Array> {\n return this.exporter(format).export(snapshot, options);\n }\n\n /**\n * Write a snapshot in a format, as one string.\n * @param snapshot - the snapshot\n * @param format - the format name\n * @param options - the exporter's common and format-specific options\n * @returns the whole document\n */\n async exportGraphToString(snapshot: GraphSnapshot, format: string, options?: ExportGraphOptions): Promise<string> {\n return this.exporter(format).exportToString(snapshot, options);\n }\n\n /**\n * What exporting a snapshot in a format would lose, without writing anything.\n * @param snapshot - the snapshot\n * @param format - the format name\n * @param options - the exporter's common and format-specific options\n * @returns the loss notes, empty when the export is exact\n */\n checkExport(snapshot: GraphSnapshot, format: string, options?: ExportGraphOptions): readonly LossNote[] {\n return this.exporter(format).check(snapshot, options);\n }\n}\n\n/**\n * A registry holding the eight built-in importers and exporters in the order of GRAPH_FORMATS.\n * @returns a new registry\n */\nexport function createRegistry(): FormatRegistry {\n return new FormatRegistry()\n .registerImporter(jsonImporter)\n .registerExporter(jsonExporter)\n .registerImporter(graphmlImporter)\n .registerExporter(graphmlExporter)\n .registerImporter(gexfImporter)\n .registerExporter(gexfExporter)\n .registerImporter(csvImporter)\n .registerExporter(csvExporter)\n .registerImporter(gmlImporter)\n .registerExporter(gmlExporter)\n .registerImporter(dotImporter)\n .registerExporter(dotExporter)\n .registerImporter(pajekImporter)\n .registerExporter(pajekExporter)\n .registerImporter(neo4jImporter)\n .registerExporter(neo4jExporter)\n .registerImporter(xgmmlImporter)\n .registerExporter(xgmmlExporter)\n .registerImporter(cx2Importer)\n .registerExporter(cx2Exporter)\n .registerImporter(cxImporter)\n .registerImporter(oboImporter)\n .registerImporter(cysImporter);\n}\n\n/** The default registry: every built-in format. */\nexport const registry: FormatRegistry = createRegistry();\n\n/**\n * Read an input into a fresh builder and freeze it, through the default registry (design section\n * 8.4: `importGraph(input, { format?, ...options })`).\n * @param input - the text, bytes, stream or chunks to read\n * @param options - the format, hints, common and format-specific import options\n * @returns the snapshot, the import report and the freeze report\n */\nexport function importGraph(input: ImportInput, options?: ImportGraphOptions): Promise<ImportGraphResult> {\n return registry.importGraph(input, options);\n}\n\n/**\n * Read every graph of an input, each into its own frozen snapshot, through the default registry.\n * @param input - the text, bytes, stream or chunks to read\n * @param options - the format, hints, common and format-specific import options\n * @returns one result per graph, in document order\n */\nexport function importAllGraphs(input: ImportInput, options?: ImportGraphOptions): Promise<ImportGraphResult[]> {\n return registry.importAllGraphs(input, options);\n}\n\n/**\n * The graphs of an input that can hold several, through the default registry.\n * @param input - the text, bytes, stream or chunks to read\n * @param options - the format, hints, common and format-specific import options\n * @returns one listing per graph, in document order; null when the format does not list its graphs\n */\nexport function listGraphs(input: ImportInput, options?: ImportGraphOptions): Promise<readonly GraphListing[] | null> {\n return registry.listGraphs(input, options);\n}\n\n/**\n * Write a snapshot in a format through the default registry, as UTF-8 chunks.\n * @param snapshot - the snapshot\n * @param format - the format name\n * @param options - the exporter's common and format-specific options\n * @returns the encoded chunks\n */\nexport function exportGraph(\n snapshot: GraphSnapshot,\n format: string,\n options?: ExportGraphOptions,\n): AsyncIterable<Uint8Array> {\n return registry.exportGraph(snapshot, format, options);\n}\n\n/**\n * Write a snapshot in a format through the default registry, as one string.\n * @param snapshot - the snapshot\n * @param format - the format name\n * @param options - the exporter's common and format-specific options\n * @returns the whole document\n */\nexport async function exportGraphToString(\n snapshot: GraphSnapshot,\n format: string,\n options?: ExportGraphOptions,\n): Promise<string> {\n return registry.exportGraphToString(snapshot, format, options);\n}\n\n/**\n * What exporting a snapshot in a format would lose, through the default registry.\n * @param snapshot - the snapshot\n * @param format - the format name\n * @param options - the exporter's common and format-specific options\n * @returns the loss notes, empty when the export is exact\n */\nexport function checkExport(\n snapshot: GraphSnapshot,\n format: string,\n options?: ExportGraphOptions,\n): readonly LossNote[] {\n return registry.checkExport(snapshot, format, options);\n}\n\n/**\n * Sniff an input's format through the default registry.\n * @param hints - the filename, MIME type and / or head of the input\n * @returns the best candidate, or null when no built-in importer claims it\n */\nexport function sniff(hints: SniffHints): SniffResult | null {\n return registry.sniff(hints);\n}\n\n/**\n * The options handed to the importer: everything but the registry's own keys.\n * @param options - the importGraph options\n * @returns the importer's options\n */\nfunction importerOptions(options: ImportGraphOptions): CommonImportOptions {\n const out: Record<string, unknown> = {};\n for (const [key, value] of Object.entries(options)) {\n if (!REGISTRY_KEYS.has(key)) {\n out[key] = value;\n }\n }\n return out;\n}\n\n/** The importer chosen for an input, and the input to hand it. */\ninterface ChosenImporter {\n /** The importer. */\n readonly importer: GraphImporter;\n /** The sniff that chose it, or null when the caller named the format. */\n readonly sniff: SniffResult | null;\n /** The input to read: the original, or a replaying iterable for a peeked stream. */\n readonly source: ImportInput;\n /** The peeked head of a sniffed input, or null. */\n readonly peeked: PeekedInput | null;\n}\n\n/**\n * A fresh builder seeded from the common options, `directed: true` as a placeholder the importer\n * overrides from the file, that stops the import when its attributes get too sparse.\n * @param options - the importGraph options\n * @param format - the format being read\n * @returns the builder\n */\nfunction seededBuilder(options: ImportGraphOptions, format: string): GraphBuilder {\n const maxEmptyCells = maxEmptyCellsOption(options.maxEmptyCells);\n return new CellBudgetBuilder(\n {\n weightDtype: options.weightDtype ?? \"f64\",\n ...options.builder,\n directed: true,\n addMissingNodes: options.addMissingNodes ?? true,\n duplicateEdges: options.duplicateEdges ?? \"keep\",\n selfLoops: options.selfLoops ?? \"keep\",\n },\n format,\n maxEmptyCells,\n );\n}\n\n/**\n * Freeze an imported builder into an importGraph result.\n * @param chosen - the importer and its sniff\n * @param builder - the filled builder\n * @param report - the importer's report\n * @param options - the importGraph options\n * @returns the frozen result\n */\nfunction result(\n chosen: ChosenImporter,\n builder: GraphBuilder,\n report: ImportReport,\n options: ImportGraphOptions,\n): ImportGraphResult {\n const frozen = builder.freezeWithReport(options.freeze);\n return Object.freeze({\n format: chosen.importer.format,\n sniff: chosen.sniff,\n snapshot: frozen.snapshot,\n report,\n freeze: frozen.report,\n });\n}\n\n/**\n * The E_UNSUPPORTED error of a format name nothing is registered under.\n * @param kind - importer or exporter\n * @param format - the requested name\n * @param known - the registered names\n * @returns the error\n */\nfunction unknownFormat(kind: \"importer\" | \"exporter\", format: string, known: Iterable<string>): GraphFormatError {\n const supported = [...known];\n return new GraphFormatError(\n \"E_UNSUPPORTED\",\n `no ${kind} is registered for format ${JSON.stringify(format)}; known: ${supported.join(\", \")}`,\n { option: \"format\", found: format, supported },\n );\n}\n\n/**\n * The hints of an import, for the unknown-format message.\n * @param options - the importGraph options\n * @returns \" (filename ..., MIME type ...)\" or an empty string\n */\nfunction describeHints(options: ImportGraphOptions): string {\n const parts: string[] = [];\n if (typeof options.filename === \"string\" && options.filename.length > 0) {\n parts.push(`filename ${JSON.stringify(options.filename)}`);\n }\n if (typeof options.mimeType === \"string\" && options.mimeType.length > 0) {\n parts.push(`MIME type ${JSON.stringify(options.mimeType)}`);\n }\n return parts.length === 0 ? \"\" : ` (${parts.join(\", \")})`;\n}\n\n/** A head read from an input, and the input to hand the importer (the same bytes, replayed for a stream). */\ninterface PeekedInput {\n /** The first bytes (or, for a text input, characters) of the content. */\n readonly head: Uint8Array | string;\n /** The input to read: the original for in-memory input, a replaying iterable for a stream. */\n readonly input: ImportInput;\n /**\n * Close the source when the importer never iterated the replaying input (it threw first, an\n * abort for instance): a stream's reader is cancelled and released, an async generator finalised.\n * @returns when the source is closed\n */\n close(): Promise<void>;\n}\n\n/**\n * The first `bytes` of an input without consuming it: in-memory input is sliced; a stream or an\n * async iterable is read until enough is buffered and then replayed (the buffered chunks first,\n * the rest as it arrives) through a new async iterable that cancels the source when the importer\n * stops early.\n * @param input - the input\n * @param bytes - how much to peek\n * @param signal - the cancellation signal, or null\n * @returns the head and the input to read\n */\nasync function peekHead(input: ImportInput, bytes: number, signal: AbortSignal | null): Promise<PeekedInput> {\n if (typeof input === \"string\") {\n return { head: input.slice(0, bytes), input, close: (): Promise<void> => Promise.resolve() };\n }\n if (input instanceof Uint8Array) {\n return { head: input.subarray(0, bytes), input, close: (): Promise<void> => Promise.resolve() };\n }\n throwIfAborted(signal);\n const source: AsyncIterator<string | Uint8Array> =\n typeof (input as { getReader?: unknown }).getReader === \"function\"\n ? readerIterator(input as ReadableStream<Uint8Array>)\n : (input as AsyncIterable<string | Uint8Array>)[Symbol.asyncIterator]();\n const buffered: (string | Uint8Array)[] = [];\n let size = 0;\n let finished = false;\n while (size < bytes) {\n if (signal !== null && signal.aborted) {\n await source.return?.();\n throwIfAborted(signal);\n }\n const next = await source.next();\n if (next.done === true) {\n finished = true;\n break;\n }\n buffered.push(next.value);\n size += typeof next.value === \"string\" ? next.value.length : next.value.byteLength;\n }\n if (!finished && signal !== null && signal.aborted) {\n // an abort that landed on the read completing the head: close the source before rethrowing\n await source.return?.();\n throwIfAborted(signal);\n }\n const replayed = replay(buffered, source, finished);\n return { head: joinHead(buffered, bytes), input: replayed, close: (): Promise<void> => replayed.close() };\n}\n\n/**\n * The head text or bytes of the buffered chunks: bytes when every chunk is bytes, text otherwise\n * (byte chunks decoded leniently; the importer decodes the real input strictly).\n * @param chunks - the buffered chunks\n * @param bytes - the head size\n * @returns the head\n */\nfunction joinHead(chunks: readonly (string | Uint8Array)[], bytes: number): Uint8Array | string {\n if (chunks.every((c) => c instanceof Uint8Array)) {\n const total = Math.min(\n bytes,\n chunks.reduce((sum, c) => sum + c.byteLength, 0),\n );\n const head = new Uint8Array(total);\n let offset = 0;\n for (const chunk of chunks) {\n if (offset >= total) {\n break;\n }\n const part = chunk.subarray(0, Math.min(chunk.byteLength, total - offset));\n head.set(part, offset);\n offset += part.byteLength;\n }\n return head;\n }\n const decoder = new TextDecoder(\"utf-8\", { fatal: false });\n let text = \"\";\n for (const chunk of chunks) {\n text += typeof chunk === \"string\" ? chunk : decoder.decode(chunk, { stream: true });\n if (text.length >= bytes) {\n break;\n }\n }\n return text.slice(0, bytes);\n}\n\n/**\n * An async iterable that yields the buffered chunks, then the rest of the source; the source is\n * closed when the consumer stops early.\n * @param buffered - the chunks already read\n * @param source - the iterator positioned after them\n * @param finished - whether the source is already exhausted\n * @returns the replaying iterable\n */\nfunction replay(\n buffered: readonly (string | Uint8Array)[],\n source: AsyncIterator<string | Uint8Array>,\n finished: boolean,\n): AsyncIterable<string | Uint8Array> & { close(): Promise<void> } {\n let exhausted = finished;\n const close = async (): Promise<void> => {\n if (!exhausted) {\n exhausted = true;\n await source.return?.();\n }\n };\n return {\n close,\n [Symbol.asyncIterator](): AsyncIterator<string | Uint8Array> {\n let position = 0;\n return {\n async next(): Promise<IteratorResult<string | Uint8Array>> {\n if (position < buffered.length) {\n return { done: false, value: buffered[position++] };\n }\n if (exhausted) {\n return { done: true, value: undefined };\n }\n const next = await source.next();\n if (next.done === true) {\n exhausted = true;\n return { done: true, value: undefined };\n }\n return next;\n },\n async return(): Promise<IteratorResult<string | Uint8Array>> {\n await close();\n return { done: true, value: undefined };\n },\n };\n },\n };\n}\n\n/**\n * An async iterator over a ReadableStream's chunks that cancels the stream when closed early.\n * @param stream - the stream\n * @returns the iterator\n */\nfunction readerIterator(stream: ReadableStream<Uint8Array>): AsyncIterator<Uint8Array> {\n const reader = stream.getReader();\n let done = false;\n return {\n async next(): Promise<IteratorResult<Uint8Array>> {\n if (done) {\n return { done: true, value: undefined };\n }\n const result = await reader.read();\n if (result.done) {\n done = true;\n reader.releaseLock();\n return { done: true, value: undefined };\n }\n return { done: false, value: result.value };\n },\n async return(): Promise<IteratorResult<Uint8Array>> {\n if (!done) {\n done = true;\n await reader.cancel().catch(() => undefined);\n reader.releaseLock();\n }\n return { done: true, value: undefined };\n },\n };\n}\n"],"names":["i","sniff","c","result"],"mappings":"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"}
|
package/dist/graphml.js
CHANGED
package/dist/json.js
CHANGED
package/dist/neo4j.js
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { c as checkRecordSyntax, R as RecordReader, B as BAD_QUOTE_CODE, U as UNCLOSED_QUOTE_CODE } from "./chunks/records-
|
|
1
|
+
import { R as ROLE_TAKEN_CODE$1, I as ID_MERGED_CODE$1, d as DUPLICATE_NODE_CODE$1, e as MISSING_ENDPOINT_CODE$1, f as MISSING_ID_CODE$1, v as resolveImportOptions, w as ImportReportBuilder, F as reportSinkOptions, z as reportUnusedOptions, y as throwIfAborted, K as IdCoercer, J as DirectionResolver, ao as ImportError, aK as declareAttribute, aW as declareOn, Q as uniqueColumnName, at as RENAMED_CODE, aL as parseDeclaredTemporal, aM as parseDeclaredValue, aN as losesPrecision, aA as declareCompanion, P as PRECISION_CODE, aP as splitListText, aF as isImportInput, aX as takenIn, aC as inputLength, a8 as ID_TEXT_COLLISION_CODE, b as ID_TEXT_TYPE_CODE, V as resolveExportOptions, X as pairFolding, aS as mapDeclaredType, aE as isCanonicalIntegerText, aU as formatTemporal, S as SINK_OPTION_CODE, O as OPTION_IGNORED_CODE, C as COLUMN_RENAMED_CODE, k as UNKNOWN_ATTR_TYPE_CODE, q as UNKNOWN_ENCODING_CODE, E as ENCODING_FALLBACK_CODE, r as INVALID_ENCODING_CODE, s as INVALID_UTF8_CODE, a7 as WEIGHT_KEY_CLASH_CODE, ac as ROLE_DROPPED_CODE, aa as MUTUAL_EXPANDED_CODE } from "./chunks/report-B1z4WT9e.js";
|
|
2
|
+
import { c as checkRecordSyntax, R as RecordReader, B as BAD_QUOTE_CODE, U as UNCLOSED_QUOTE_CODE } from "./chunks/records-dbRkxwaq.js";
|
|
3
3
|
import { GraphFormatError, INVALID_INDEX } from "@graphty/graph-format";
|
|
4
|
-
import { m as quoteCsvCell } from "./chunks/escape-
|
|
5
|
-
import { c as capabilities,
|
|
6
|
-
import { p as parseWeightText, e as explicitWeights,
|
|
4
|
+
import { m as quoteCsvCell } from "./chunks/escape-B-tkk_Cl.js";
|
|
5
|
+
import { c as capabilities, a as checkCapabilities, L as LOSS } from "./chunks/export-Bh60Dv-n.js";
|
|
6
|
+
import { p as parseWeightText, e as explicitWeights, a as formatF64, f as formatF32, d as formatInteger } from "./chunks/weights-Dzba96G3.js";
|
|
7
|
+
import { j as joinText, e as encodeChunks } from "./chunks/writer-C7flM-Ih.js";
|
|
7
8
|
const STRUCTURAL = /* @__PURE__ */ new Set(["ID", "LABEL", "START_ID", "END_ID", "TYPE", "IGNORE"]);
|
|
8
9
|
const SPACE_KINDS = /* @__PURE__ */ new Set(["ID", "START_ID", "END_ID"]);
|
|
9
10
|
const HEADER_MARKER = /^[^:{}()]*:\s*(ID|START_ID|END_ID)\s*(\(|\{|$)/i;
|