@osmix/gtfs 0.0.2 → 0.0.3

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/CHANGELOG.md CHANGED
@@ -1,5 +1,15 @@
1
1
  # @osmix/gtfs
2
2
 
3
+ ## 0.0.3
4
+
5
+ ### Patch Changes
6
+
7
+ - f468db5: Fix publishing (2)
8
+ - 536a3cd: Remove JSR dependency for CSV parsing
9
+ - Updated dependencies [f468db5]
10
+ - @osmix/core@0.1.3
11
+ - @osmix/shared@0.0.8
12
+
3
13
  ## 0.0.2
4
14
 
5
15
  ### Patch Changes
package/README.md CHANGED
@@ -196,5 +196,6 @@ Class for more fine-grained control over the conversion process.
196
196
  ## Dependencies
197
197
 
198
198
  - [but-unzip](https://github.com/nicolo-ribaudo/but-unzip) - ZIP file parsing
199
- - [@std/csv](https://jsr.io/@std/csv) - Streaming CSV parsing (from Deno standard library)
199
+ - [csv-parse](https://www.npmjs.com/package/csv-parse) - CSV parsing from the csv npm
200
+ project
200
201
  - [@osmix/core](../core) - OSM data structures
@@ -1,8 +1,8 @@
1
1
  /**
2
- * Lazy GTFS archive parser with streaming CSV support.
2
+ * Lazy GTFS archive parser.
3
3
  *
4
4
  * Only parses CSV files when they are accessed, not upfront.
5
- * Uses @std/csv CsvParseStream for true line-by-line streaming.
5
+ * Uses csv-parse from npm for CSV parsing.
6
6
  *
7
7
  * @module
8
8
  */
@@ -24,9 +24,8 @@ export type GtfsFileName = keyof GtfsFileTypeMap;
24
24
  * Lazy GTFS archive that only parses files on demand.
25
25
  *
26
26
  * Files are read from the zip and parsed only when their
27
- * corresponding getter is called for the first time.
28
- * Streaming iterators parse CSV line-by-line without loading
29
- * the entire file into memory.
27
+ * corresponding iterator is called for the first time.
28
+ * Iterators yield typed rows one record at a time.
30
29
  */
31
30
  export declare class GtfsArchive {
32
31
  private entries;
@@ -1 +1 @@
1
- {"version":3,"file":"gtfs-archive.d.ts","sourceRoot":"","sources":["../src/gtfs-archive.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAIH,OAAO,KAAK,EACX,UAAU,EACV,SAAS,EACT,cAAc,EACd,QAAQ,EACR,YAAY,EACZ,QAAQ,EACR,MAAM,SAAS,CAAA;AAGhB;;GAEG;AACH,MAAM,WAAW,eAAe;IAC/B,YAAY,EAAE,UAAU,CAAA;IACxB,WAAW,EAAE,QAAQ,CAAA;IACrB,YAAY,EAAE,SAAS,CAAA;IACvB,WAAW,EAAE,QAAQ,CAAA;IACrB,gBAAgB,EAAE,YAAY,CAAA;IAC9B,YAAY,EAAE,cAAc,CAAA;CAC5B;AAED,+CAA+C;AAC/C,MAAM,MAAM,YAAY,GAAG,MAAM,eAAe,CAAA;AAEhD;;;;;;;GAOG;AACH,qBAAa,WAAW;IACvB,OAAO,CAAC,OAAO,CAAsB;IAErC,OAAO;IAIP;;OAEG;IACH,MAAM,CAAC,OAAO,CAAC,OAAO,EAAE,WAAW,GAAG,UAAU,GAAG,WAAW;IAiB9D;;OAEG;IACH,OAAO,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO;IAIlC;;OAEG;IACH,SAAS,IAAI,MAAM,EAAE;IAIrB;;OAEG;YACW,YAAY;IAQ1B;;;;;;;;;;;;;;;;;;OAkBG;IACI,IAAI,CAAC,CAAC,SAAS,YAAY,EACjC,QAAQ,EAAE,CAAC,GACT,cAAc,CAAC,eAAe,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,OAAO,CAAC;CAoBpD"}
1
+ {"version":3,"file":"gtfs-archive.d.ts","sourceRoot":"","sources":["../src/gtfs-archive.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAIH,OAAO,KAAK,EACX,UAAU,EACV,SAAS,EACT,cAAc,EACd,QAAQ,EACR,YAAY,EACZ,QAAQ,EACR,MAAM,SAAS,CAAA;AAEhB;;GAEG;AACH,MAAM,WAAW,eAAe;IAC/B,YAAY,EAAE,UAAU,CAAA;IACxB,WAAW,EAAE,QAAQ,CAAA;IACrB,YAAY,EAAE,SAAS,CAAA;IACvB,WAAW,EAAE,QAAQ,CAAA;IACrB,gBAAgB,EAAE,YAAY,CAAA;IAC9B,YAAY,EAAE,cAAc,CAAA;CAC5B;AAED,+CAA+C;AAC/C,MAAM,MAAM,YAAY,GAAG,MAAM,eAAe,CAAA;AAEhD;;;;;;GAMG;AACH,qBAAa,WAAW;IACvB,OAAO,CAAC,OAAO,CAAsB;IAErC,OAAO;IAIP;;OAEG;IACH,MAAM,CAAC,OAAO,CAAC,OAAO,EAAE,WAAW,GAAG,UAAU,GAAG,WAAW;IAiB9D;;OAEG;IACH,OAAO,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO;IAIlC;;OAEG;IACH,SAAS,IAAI,MAAM,EAAE;IAIrB;;OAEG;YACW,YAAY;IAQ1B;;;;;;;;;;;;;;;;;;OAkBG;IACI,IAAI,CAAC,CAAC,SAAS,YAAY,EACjC,QAAQ,EAAE,CAAC,GACT,cAAc,CAAC,eAAe,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,OAAO,CAAC;CAepD"}
@@ -1,21 +1,19 @@
1
1
  /**
2
- * Lazy GTFS archive parser with streaming CSV support.
2
+ * Lazy GTFS archive parser.
3
3
  *
4
4
  * Only parses CSV files when they are accessed, not upfront.
5
- * Uses @std/csv CsvParseStream for true line-by-line streaming.
5
+ * Uses csv-parse from npm for CSV parsing.
6
6
  *
7
7
  * @module
8
8
  */
9
- import { CsvParseStream } from "@std/csv/parse-stream";
9
+ import { parse } from "csv-parse/sync";
10
10
  import { unzip } from "but-unzip";
11
- import { bytesToTextStream } from "./utils";
12
11
  /**
13
12
  * Lazy GTFS archive that only parses files on demand.
14
13
  *
15
14
  * Files are read from the zip and parsed only when their
16
- * corresponding getter is called for the first time.
17
- * Streaming iterators parse CSV line-by-line without loading
18
- * the entire file into memory.
15
+ * corresponding iterator is called for the first time.
16
+ * Iterators yield typed rows one record at a time.
19
17
  */
20
18
  export class GtfsArchive {
21
19
  entries;
@@ -83,19 +81,14 @@ export class GtfsArchive {
83
81
  const bytes = await this.getFileBytes(filename);
84
82
  if (!bytes)
85
83
  return;
86
- const textStream = bytesToTextStream(bytes);
87
- const csvStream = textStream.pipeThrough(new CsvParseStream({ skipFirstRow: true }));
88
- const reader = csvStream.getReader();
89
- try {
90
- while (true) {
91
- const { value, done } = await reader.read();
92
- if (done)
93
- break;
94
- yield value;
95
- }
96
- }
97
- finally {
98
- reader.releaseLock();
84
+ const csvText = new TextDecoder().decode(bytes);
85
+ const rows = parse(csvText, {
86
+ bom: true,
87
+ columns: true,
88
+ skip_empty_lines: true,
89
+ });
90
+ for (const row of rows) {
91
+ yield row;
99
92
  }
100
93
  }
101
94
  }
@@ -1 +1 @@
1
- {"version":3,"file":"gtfs-archive.js","sourceRoot":"","sources":["../src/gtfs-archive.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAA;AACtD,OAAO,EAAE,KAAK,EAAgB,MAAM,WAAW,CAAA;AAS/C,OAAO,EAAE,iBAAiB,EAAE,MAAM,SAAS,CAAA;AAiB3C;;;;;;;GAOG;AACH,MAAM,OAAO,WAAW;IACf,OAAO,CAAsB;IAErC,YAAoB,OAA6B;QAChD,IAAI,CAAC,OAAO,GAAG,OAAO,CAAA;IACvB,CAAC;IAED;;OAEG;IACH,MAAM,CAAC,OAAO,CAAC,OAAiC;QAC/C,MAAM,KAAK,GACV,OAAO,YAAY,UAAU,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,UAAU,CAAC,OAAO,CAAC,CAAA;QAClE,MAAM,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC,CAAA;QAE1B,MAAM,OAAO,GAAG,IAAI,GAAG,EAAmB,CAAA;QAC1C,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;YAC1B,gDAAgD;YAChD,MAAM,IAAI,GAAG,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,OAAO,EAAE,EAAE,CAAC,CAAA;YAC/C,IAAI,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC;gBAC3B,OAAO,CAAC,GAAG,CAAC,IAAI,EAAE,IAAI,CAAC,CAAA;YACxB,CAAC;QACF,CAAC;QAED,OAAO,IAAI,WAAW,CAAC,OAAO,CAAC,CAAA;IAChC,CAAC;IAED;;OAEG;IACH,OAAO,CAAC,QAAgB;QACvB,OAAO,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAA;IAClC,CAAC;IAED;;OAEG;IACH,SAAS;QACR,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC,CAAA;IACvC,CAAC;IAED;;OAEG;IACK,KAAK,CAAC,YAAY,CAAC,QAAgB;QAC1C,MAAM,KAAK,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAA;QACxC,IAAI,CAAC,KAAK;YAAE,OAAO,IAAI,CAAA;QAEvB,MAAM,IAAI,GAAG,KAAK,CAAC,IAAI,EAAE,CAAA;QACzB,OAAO,IAAI,YAAY,OAAO,CAAC,CAAC,CAAC,MAAM,IAAI,CAAC,CAAC,CAAC,IAAI,CAAA;IACnD,CAAC;IAED;;;;;;;;;;;;;;;;;;OAkBG;IACH,KAAK,CAAC,CAAC,IAAI,CACV,QAAW;QAEX,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,YAAY,CAAC,QAAQ,CAAC,CAAA;QAC/C,IAAI,CAAC,KAAK;YAAE,OAAM;QAElB,MAAM,UAAU,GAAG,iBAAiB,CAAC,KAAK,CAAC,CAAA;QAC3C,MAAM,SAAS,GAAG,UAAU,CAAC,WAAW,CACvC,IAAI,cAAc,CAAC,EAAE,YAAY,EAAE,IAAI,EAAE,CAAC,CAC1C,CAAA;QAED,MAAM,MAAM,GAAG,SAAS,CAAC,SAAS,EAAE,CAAA;QACpC,IAAI,CAAC;YACJ,OAAO,IAAI,EAAE,CAAC;gBACb,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,GAAG,MAAM,MAAM,CAAC,IAAI,EAAE,CAAA;gBAC3C,IAAI,IAAI;oBAAE,MAAK;gBACf,MAAM,KAAsC,CAAA;YAC7C,CAAC;QACF,CAAC;gBAAS,CAAC;YACV,MAAM,CAAC,WAAW,EAAE,CAAA;QACrB,CAAC;IACF,CAAC;CACD"}
1
+ {"version":3,"file":"gtfs-archive.js","sourceRoot":"","sources":["../src/gtfs-archive.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,KAAK,EAAE,MAAM,gBAAgB,CAAA;AACtC,OAAO,EAAE,KAAK,EAAgB,MAAM,WAAW,CAAA;AAyB/C;;;;;;GAMG;AACH,MAAM,OAAO,WAAW;IACf,OAAO,CAAsB;IAErC,YAAoB,OAA6B;QAChD,IAAI,CAAC,OAAO,GAAG,OAAO,CAAA;IACvB,CAAC;IAED;;OAEG;IACH,MAAM,CAAC,OAAO,CAAC,OAAiC;QAC/C,MAAM,KAAK,GACV,OAAO,YAAY,UAAU,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,UAAU,CAAC,OAAO,CAAC,CAAA;QAClE,MAAM,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC,CAAA;QAE1B,MAAM,OAAO,GAAG,IAAI,GAAG,EAAmB,CAAA;QAC1C,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;YAC1B,gDAAgD;YAChD,MAAM,IAAI,GAAG,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,OAAO,EAAE,EAAE,CAAC,CAAA;YAC/C,IAAI,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC;gBAC3B,OAAO,CAAC,GAAG,CAAC,IAAI,EAAE,IAAI,CAAC,CAAA;YACxB,CAAC;QACF,CAAC;QAED,OAAO,IAAI,WAAW,CAAC,OAAO,CAAC,CAAA;IAChC,CAAC;IAED;;OAEG;IACH,OAAO,CAAC,QAAgB;QACvB,OAAO,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAA;IAClC,CAAC;IAED;;OAEG;IACH,SAAS;QACR,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC,CAAA;IACvC,CAAC;IAED;;OAEG;IACK,KAAK,CAAC,YAAY,CAAC,QAAgB;QAC1C,MAAM,KAAK,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAA;QACxC,IAAI,CAAC,KAAK;YAAE,OAAO,IAAI,CAAA;QAEvB,MAAM,IAAI,GAAG,KAAK,CAAC,IAAI,EAAE,CAAA;QACzB,OAAO,IAAI,YAAY,OAAO,CAAC,CAAC,CAAC,MAAM,IAAI,CAAC,CAAC,CAAC,IAAI,CAAA;IACnD,CAAC;IAED;;;;;;;;;;;;;;;;;;OAkBG;IACH,KAAK,CAAC,CAAC,IAAI,CACV,QAAW;QAEX,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,YAAY,CAAC,QAAQ,CAAC,CAAA;QAC/C,IAAI,CAAC,KAAK;YAAE,OAAM;QAElB,MAAM,OAAO,GAAG,IAAI,WAAW,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,CAAA;QAC/C,MAAM,IAAI,GAAG,KAAK,CAAyB,OAAO,EAAE;YACnD,GAAG,EAAE,IAAI;YACT,OAAO,EAAE,IAAI;YACb,gBAAgB,EAAE,IAAI;SACtB,CAAC,CAAA;QAEF,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;YACxB,MAAM,GAAoC,CAAA;QAC3C,CAAC;IACF,CAAC;CACD"}
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "$schema": "https://json.schemastore.org/package",
3
3
  "name": "@osmix/gtfs",
4
4
  "description": "Convert GTFS transit feeds to OSM format.",
5
- "version": "0.0.2",
5
+ "version": "0.0.3",
6
6
  "type": "module",
7
7
  "main": "./src/index.ts",
8
8
  "types": "./src/index.ts",
@@ -47,9 +47,9 @@
47
47
  "typescript": "^5.9.0"
48
48
  },
49
49
  "dependencies": {
50
- "@osmix/core": "0.1.2",
51
- "@osmix/shared": "0.0.7",
52
- "@std/csv": "npm:@jsr/std__csv",
53
- "but-unzip": "^0.1.7"
50
+ "@osmix/core": "0.1.3",
51
+ "@osmix/shared": "0.0.8",
52
+ "but-unzip": "^0.1.7",
53
+ "csv-parse": "^6.1.0"
54
54
  }
55
55
  }
@@ -1,13 +1,13 @@
1
1
  /**
2
- * Lazy GTFS archive parser with streaming CSV support.
2
+ * Lazy GTFS archive parser.
3
3
  *
4
4
  * Only parses CSV files when they are accessed, not upfront.
5
- * Uses @std/csv CsvParseStream for true line-by-line streaming.
5
+ * Uses csv-parse from npm for CSV parsing.
6
6
  *
7
7
  * @module
8
8
  */
9
9
 
10
- import { CsvParseStream } from "@std/csv/parse-stream"
10
+ import { parse } from "csv-parse/sync"
11
11
  import { unzip, type ZipItem } from "but-unzip"
12
12
  import type {
13
13
  GtfsAgency,
@@ -17,7 +17,6 @@ import type {
17
17
  GtfsStopTime,
18
18
  GtfsTrip,
19
19
  } from "./types"
20
- import { bytesToTextStream } from "./utils"
21
20
 
22
21
  /**
23
22
  * Map of GTFS filenames to their record types.
@@ -38,9 +37,8 @@ export type GtfsFileName = keyof GtfsFileTypeMap
38
37
  * Lazy GTFS archive that only parses files on demand.
39
38
  *
40
39
  * Files are read from the zip and parsed only when their
41
- * corresponding getter is called for the first time.
42
- * Streaming iterators parse CSV line-by-line without loading
43
- * the entire file into memory.
40
+ * corresponding iterator is called for the first time.
41
+ * Iterators yield typed rows one record at a time.
44
42
  */
45
43
  export class GtfsArchive {
46
44
  private entries: Map<string, ZipItem>
@@ -119,20 +117,15 @@ export class GtfsArchive {
119
117
  const bytes = await this.getFileBytes(filename)
120
118
  if (!bytes) return
121
119
 
122
- const textStream = bytesToTextStream(bytes)
123
- const csvStream = textStream.pipeThrough(
124
- new CsvParseStream({ skipFirstRow: true }),
125
- )
120
+ const csvText = new TextDecoder().decode(bytes)
121
+ const rows = parse<Record<string, string>>(csvText, {
122
+ bom: true,
123
+ columns: true,
124
+ skip_empty_lines: true,
125
+ })
126
126
 
127
- const reader = csvStream.getReader()
128
- try {
129
- while (true) {
130
- const { value, done } = await reader.read()
131
- if (done) break
132
- yield value as unknown as GtfsFileTypeMap[F]
133
- }
134
- } finally {
135
- reader.releaseLock()
127
+ for (const row of rows) {
128
+ yield row as unknown as GtfsFileTypeMap[F]
136
129
  }
137
130
  }
138
131
  }
@@ -201,6 +201,21 @@ describe("GtfsArchive", () => {
201
201
  expect(routes[0]?.route_short_name).toBe("1")
202
202
  })
203
203
 
204
+ test("parses quoted CSV fields", async () => {
205
+ const { zipSync } = await import("fflate")
206
+ const encoder = new TextEncoder()
207
+ const zipData = zipSync({
208
+ "stops.txt": encoder.encode(`stop_id,stop_name,stop_lat,stop_lon
209
+ stop1,"Main ""Central"", Downtown",40.7128,-74.0060`),
210
+ })
211
+
212
+ const archive = GtfsArchive.fromZip(zipData)
213
+ const stops = await Array.fromAsync(archive.iter("stops.txt"))
214
+
215
+ expect(stops.length).toBe(1)
216
+ expect(stops[0]?.stop_name).toBe('Main "Central", Downtown')
217
+ })
218
+
204
219
  test("iterates stops without loading all at once", async () => {
205
220
  const zipData = await createTestGtfsZip()
206
221
  const archive = GtfsArchive.fromZip(zipData)