gtfs-sqljs 0.2.2 → 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/README.md +3 -2
- package/dist/index.d.ts +19 -13
- package/dist/index.js +94 -94
- package/dist/index.js.map +1 -1
- package/package.json +2 -1
package/README.md
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
<div align="center">
|
|
2
|
-
<img src="logo.svg" alt="gtfs-sqljs logo" width="200" height="200">
|
|
2
|
+
<img src="illustrations/logo.svg" alt="gtfs-sqljs logo" width="200" height="200">
|
|
3
3
|
<h1>gtfs-sqljs</h1>
|
|
4
4
|
|
|
5
5
|
[](https://www.npmjs.com/package/gtfs-sqljs)
|
|
@@ -97,7 +97,8 @@ Full API documentation: [API Reference](https://sysdevrun.github.io/gtfs-sqljs/d
|
|
|
97
97
|
|
|
98
98
|
### Static Methods
|
|
99
99
|
|
|
100
|
-
- `GtfsSqlJs.fromZip(zipPath, options?)` - Create instance from GTFS ZIP file
|
|
100
|
+
- `GtfsSqlJs.fromZip(zipPath, options?)` - Create instance from GTFS ZIP file path or URL
|
|
101
|
+
- `GtfsSqlJs.fromZipData(zipData, options?)` - Create instance from pre-loaded GTFS ZIP data (`ArrayBuffer` or `Uint8Array`)
|
|
101
102
|
- `GtfsSqlJs.fromDatabase(database, options?)` - Create instance from existing database
|
|
102
103
|
|
|
103
104
|
### Instance Methods
|
package/dist/index.d.ts
CHANGED
|
@@ -292,8 +292,8 @@ interface Agency {
|
|
|
292
292
|
interface Stop {
|
|
293
293
|
stop_id: string;
|
|
294
294
|
stop_name: string;
|
|
295
|
-
stop_lat
|
|
296
|
-
stop_lon
|
|
295
|
+
stop_lat?: number;
|
|
296
|
+
stop_lon?: number;
|
|
297
297
|
stop_code?: string;
|
|
298
298
|
stop_desc?: string;
|
|
299
299
|
zone_id?: string;
|
|
@@ -310,8 +310,8 @@ interface Stop {
|
|
|
310
310
|
*/
|
|
311
311
|
interface Route {
|
|
312
312
|
route_id: string;
|
|
313
|
-
route_short_name
|
|
314
|
-
route_long_name
|
|
313
|
+
route_short_name?: string;
|
|
314
|
+
route_long_name?: string;
|
|
315
315
|
route_type: number;
|
|
316
316
|
agency_id?: string;
|
|
317
317
|
route_desc?: string;
|
|
@@ -342,8 +342,8 @@ interface Trip {
|
|
|
342
342
|
*/
|
|
343
343
|
interface StopTime {
|
|
344
344
|
trip_id: string;
|
|
345
|
-
arrival_time
|
|
346
|
-
departure_time
|
|
345
|
+
arrival_time?: string;
|
|
346
|
+
departure_time?: string;
|
|
347
347
|
stop_id: string;
|
|
348
348
|
stop_sequence: number;
|
|
349
349
|
stop_headsign?: string;
|
|
@@ -426,7 +426,7 @@ interface Frequency {
|
|
|
426
426
|
interface Transfer {
|
|
427
427
|
from_stop_id: string;
|
|
428
428
|
to_stop_id: string;
|
|
429
|
-
transfer_type
|
|
429
|
+
transfer_type?: number;
|
|
430
430
|
min_transfer_time?: number;
|
|
431
431
|
}
|
|
432
432
|
/**
|
|
@@ -714,19 +714,25 @@ declare class GtfsSqlJs {
|
|
|
714
714
|
*/
|
|
715
715
|
private constructor();
|
|
716
716
|
/**
|
|
717
|
-
* Create GtfsSqlJs instance from GTFS ZIP file
|
|
717
|
+
* Create GtfsSqlJs instance from GTFS ZIP file path or URL
|
|
718
718
|
*/
|
|
719
719
|
static fromZip(zipPath: string, options?: Omit<GtfsSqlJsOptions, 'zipPath' | 'database'>): Promise<GtfsSqlJs>;
|
|
720
|
+
/**
|
|
721
|
+
* Create GtfsSqlJs instance from pre-loaded GTFS ZIP data
|
|
722
|
+
* @param source - Optional original path/URL, used for cache key generation and metadata
|
|
723
|
+
*/
|
|
724
|
+
static fromZipData(zipData: ArrayBuffer | Uint8Array, options?: Omit<GtfsSqlJsOptions, 'zipPath' | 'database'>, source?: string): Promise<GtfsSqlJs>;
|
|
720
725
|
/**
|
|
721
726
|
* Create GtfsSqlJs instance from existing SQLite database
|
|
722
727
|
*/
|
|
723
728
|
static fromDatabase(database: ArrayBuffer, options?: Omit<GtfsSqlJsOptions, 'zipPath' | 'database'>): Promise<GtfsSqlJs>;
|
|
724
729
|
/**
|
|
725
|
-
* Initialize from ZIP
|
|
730
|
+
* Initialize from pre-loaded ZIP data
|
|
731
|
+
* @param source - Optional original path/URL, used for cache key generation and metadata
|
|
726
732
|
*/
|
|
727
|
-
private
|
|
733
|
+
private initFromZipData;
|
|
728
734
|
/**
|
|
729
|
-
* Helper method to load GTFS data from zip data
|
|
735
|
+
* Helper method to load GTFS data from zip data
|
|
730
736
|
* Used by both cache-enabled and cache-disabled paths
|
|
731
737
|
*/
|
|
732
738
|
private loadFromZipData;
|
|
@@ -1058,8 +1064,8 @@ interface IndexDefinition {
|
|
|
1058
1064
|
declare const GTFS_SCHEMA: TableSchema[];
|
|
1059
1065
|
|
|
1060
1066
|
/**
|
|
1061
|
-
* Compute SHA-256 checksum of data
|
|
1062
|
-
* Uses Web Crypto API (available in
|
|
1067
|
+
* Compute SHA-256 checksum of data.
|
|
1068
|
+
* Uses the global Web Crypto API (available in browsers and Node.js 18+).
|
|
1063
1069
|
*/
|
|
1064
1070
|
declare function computeChecksum(data: ArrayBuffer | Uint8Array): Promise<string>;
|
|
1065
1071
|
/**
|
package/dist/index.js
CHANGED
|
@@ -69,8 +69,8 @@ var GTFS_SCHEMA = [
|
|
|
69
69
|
columns: [
|
|
70
70
|
{ name: "stop_id", type: "TEXT", required: true, primaryKey: true },
|
|
71
71
|
{ name: "stop_name", type: "TEXT", required: true },
|
|
72
|
-
{ name: "stop_lat", type: "REAL", required:
|
|
73
|
-
{ name: "stop_lon", type: "REAL", required:
|
|
72
|
+
{ name: "stop_lat", type: "REAL", required: false },
|
|
73
|
+
{ name: "stop_lon", type: "REAL", required: false },
|
|
74
74
|
{ name: "stop_code", type: "TEXT", required: false },
|
|
75
75
|
{ name: "stop_desc", type: "TEXT", required: false },
|
|
76
76
|
{ name: "zone_id", type: "TEXT", required: false },
|
|
@@ -92,8 +92,8 @@ var GTFS_SCHEMA = [
|
|
|
92
92
|
name: "routes",
|
|
93
93
|
columns: [
|
|
94
94
|
{ name: "route_id", type: "TEXT", required: true, primaryKey: true },
|
|
95
|
-
{ name: "route_short_name", type: "TEXT", required:
|
|
96
|
-
{ name: "route_long_name", type: "TEXT", required:
|
|
95
|
+
{ name: "route_short_name", type: "TEXT", required: false },
|
|
96
|
+
{ name: "route_long_name", type: "TEXT", required: false },
|
|
97
97
|
{ name: "route_type", type: "INTEGER", required: true },
|
|
98
98
|
{ name: "agency_id", type: "TEXT", required: false },
|
|
99
99
|
{ name: "route_desc", type: "TEXT", required: false },
|
|
@@ -132,8 +132,8 @@ var GTFS_SCHEMA = [
|
|
|
132
132
|
name: "stop_times",
|
|
133
133
|
columns: [
|
|
134
134
|
{ name: "trip_id", type: "TEXT", required: true },
|
|
135
|
-
{ name: "arrival_time", type: "TEXT", required:
|
|
136
|
-
{ name: "departure_time", type: "TEXT", required:
|
|
135
|
+
{ name: "arrival_time", type: "TEXT", required: false },
|
|
136
|
+
{ name: "departure_time", type: "TEXT", required: false },
|
|
137
137
|
{ name: "stop_id", type: "TEXT", required: true },
|
|
138
138
|
{ name: "stop_sequence", type: "INTEGER", required: true },
|
|
139
139
|
{ name: "stop_headsign", type: "TEXT", required: false },
|
|
@@ -236,7 +236,7 @@ var GTFS_SCHEMA = [
|
|
|
236
236
|
columns: [
|
|
237
237
|
{ name: "from_stop_id", type: "TEXT", required: true },
|
|
238
238
|
{ name: "to_stop_id", type: "TEXT", required: true },
|
|
239
|
-
{ name: "transfer_type", type: "INTEGER", required:
|
|
239
|
+
{ name: "transfer_type", type: "INTEGER", required: false },
|
|
240
240
|
{ name: "min_transfer_time", type: "INTEGER", required: false }
|
|
241
241
|
],
|
|
242
242
|
indexes: [
|
|
@@ -340,25 +340,28 @@ function getAllCreateIndexStatements() {
|
|
|
340
340
|
|
|
341
341
|
// src/loaders/zip-loader.ts
|
|
342
342
|
import JSZip from "jszip";
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
343
|
+
|
|
344
|
+
// src/utils/env.ts
|
|
345
|
+
function isNodeEnvironment() {
|
|
346
|
+
return typeof process !== "undefined" && process.versions != null && process.versions.node != null;
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
// src/loaders/zip-loader.ts
|
|
350
|
+
async function loadGTFSZip(zipData, skipFiles) {
|
|
350
351
|
const zip = await JSZip.loadAsync(zipData);
|
|
352
|
+
const skipSet = skipFiles ? new Set(skipFiles) : null;
|
|
351
353
|
const files = {};
|
|
352
354
|
const filePromises = [];
|
|
353
355
|
zip.forEach((relativePath, file) => {
|
|
354
|
-
if (
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
356
|
+
if (file.dir) return;
|
|
357
|
+
const fileName = relativePath.split("/").pop() || relativePath;
|
|
358
|
+
if (!(fileName in GTFS_FILE_MAPPING)) return;
|
|
359
|
+
if (skipSet?.has(fileName)) return;
|
|
360
|
+
filePromises.push(
|
|
361
|
+
file.async("string").then((content) => {
|
|
362
|
+
files[fileName] = content;
|
|
363
|
+
})
|
|
364
|
+
);
|
|
362
365
|
});
|
|
363
366
|
await Promise.all(filePromises);
|
|
364
367
|
return files;
|
|
@@ -411,8 +414,7 @@ async function fetchZip(source, onProgress) {
|
|
|
411
414
|
}
|
|
412
415
|
throw new Error("fetch is not available to load URL");
|
|
413
416
|
}
|
|
414
|
-
|
|
415
|
-
if (isNode) {
|
|
417
|
+
if (isNodeEnvironment()) {
|
|
416
418
|
try {
|
|
417
419
|
const fs = await import("fs");
|
|
418
420
|
const buffer = await fs.promises.readFile(source);
|
|
@@ -430,6 +432,24 @@ async function fetchZip(source, onProgress) {
|
|
|
430
432
|
}
|
|
431
433
|
throw new Error("No method available to load ZIP file");
|
|
432
434
|
}
|
|
435
|
+
var GTFS_FILE_MAPPING = {
|
|
436
|
+
"agency.txt": "agency",
|
|
437
|
+
"stops.txt": "stops",
|
|
438
|
+
"routes.txt": "routes",
|
|
439
|
+
"trips.txt": "trips",
|
|
440
|
+
"stop_times.txt": "stop_times",
|
|
441
|
+
"calendar.txt": "calendar",
|
|
442
|
+
"calendar_dates.txt": "calendar_dates",
|
|
443
|
+
"fare_attributes.txt": "fare_attributes",
|
|
444
|
+
"fare_rules.txt": "fare_rules",
|
|
445
|
+
"shapes.txt": "shapes",
|
|
446
|
+
"frequencies.txt": "frequencies",
|
|
447
|
+
"transfers.txt": "transfers",
|
|
448
|
+
"pathways.txt": "pathways",
|
|
449
|
+
"levels.txt": "levels",
|
|
450
|
+
"feed_info.txt": "feed_info",
|
|
451
|
+
"attributions.txt": "attributions"
|
|
452
|
+
};
|
|
433
453
|
|
|
434
454
|
// src/loaders/csv-parser.ts
|
|
435
455
|
import Papa from "papaparse";
|
|
@@ -867,8 +887,7 @@ async function fetchProtobuf(source) {
|
|
|
867
887
|
const arrayBuffer2 = await response2.arrayBuffer();
|
|
868
888
|
return new Uint8Array(arrayBuffer2);
|
|
869
889
|
}
|
|
870
|
-
|
|
871
|
-
if (isNode) {
|
|
890
|
+
if (isNodeEnvironment()) {
|
|
872
891
|
try {
|
|
873
892
|
const fs = await import("fs");
|
|
874
893
|
const buffer = await fs.promises.readFile(source);
|
|
@@ -898,24 +917,13 @@ function loadGtfsRtProto() {
|
|
|
898
917
|
function camelToSnake(str) {
|
|
899
918
|
return str.replace(/[A-Z]/g, (letter) => `_${letter.toLowerCase()}`);
|
|
900
919
|
}
|
|
901
|
-
function
|
|
902
|
-
|
|
903
|
-
|
|
920
|
+
function convertObjectKeysToSnakeCase(obj) {
|
|
921
|
+
const result = {};
|
|
922
|
+
for (const [key, value] of Object.entries(obj)) {
|
|
923
|
+
const snakeKey = camelToSnake(key);
|
|
924
|
+
result[snakeKey] = value !== null && typeof value === "object" && !Array.isArray(value) ? convertObjectKeysToSnakeCase(value) : value;
|
|
904
925
|
}
|
|
905
|
-
|
|
906
|
-
return obj.map(convertKeysToSnakeCase);
|
|
907
|
-
}
|
|
908
|
-
if (typeof obj === "object") {
|
|
909
|
-
const result = {};
|
|
910
|
-
for (const key in obj) {
|
|
911
|
-
if (Object.prototype.hasOwnProperty.call(obj, key)) {
|
|
912
|
-
const snakeKey = camelToSnake(key);
|
|
913
|
-
result[snakeKey] = convertKeysToSnakeCase(obj[key]);
|
|
914
|
-
}
|
|
915
|
-
}
|
|
916
|
-
return result;
|
|
917
|
-
}
|
|
918
|
-
return obj;
|
|
926
|
+
return result;
|
|
919
927
|
}
|
|
920
928
|
function parseTranslatedString(ts) {
|
|
921
929
|
if (!ts || !ts.translation || ts.translation.length === 0) {
|
|
@@ -936,8 +944,8 @@ function insertAlerts(db, alerts, timestamp) {
|
|
|
936
944
|
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
937
945
|
`);
|
|
938
946
|
for (const alert of alerts) {
|
|
939
|
-
const activePeriodSnake =
|
|
940
|
-
const informedEntitySnake =
|
|
947
|
+
const activePeriodSnake = (alert.activePeriod ?? []).map(convertObjectKeysToSnakeCase);
|
|
948
|
+
const informedEntitySnake = (alert.informedEntity ?? []).map(convertObjectKeysToSnakeCase);
|
|
941
949
|
stmt.run([
|
|
942
950
|
alert.id,
|
|
943
951
|
JSON.stringify(activePeriodSnake),
|
|
@@ -1098,24 +1106,16 @@ async function loadRealtimeData(db, feedUrls) {
|
|
|
1098
1106
|
}
|
|
1099
1107
|
|
|
1100
1108
|
// src/cache/checksum.ts
|
|
1101
|
-
async function getCrypto() {
|
|
1102
|
-
if (typeof crypto !== "undefined" && crypto.subtle) {
|
|
1103
|
-
return crypto;
|
|
1104
|
-
}
|
|
1105
|
-
if (typeof globalThis !== "undefined") {
|
|
1106
|
-
try {
|
|
1107
|
-
const { webcrypto } = await import("crypto");
|
|
1108
|
-
return webcrypto;
|
|
1109
|
-
} catch {
|
|
1110
|
-
throw new Error("Web Crypto API not available");
|
|
1111
|
-
}
|
|
1112
|
-
}
|
|
1113
|
-
throw new Error("Crypto not available in this environment");
|
|
1114
|
-
}
|
|
1115
1109
|
async function computeChecksum(data) {
|
|
1116
|
-
|
|
1117
|
-
|
|
1118
|
-
|
|
1110
|
+
let buffer;
|
|
1111
|
+
if (data instanceof ArrayBuffer) {
|
|
1112
|
+
buffer = data;
|
|
1113
|
+
} else {
|
|
1114
|
+
const copy = new ArrayBuffer(data.byteLength);
|
|
1115
|
+
new Uint8Array(copy).set(data);
|
|
1116
|
+
buffer = copy;
|
|
1117
|
+
}
|
|
1118
|
+
const hashBuffer = await crypto.subtle.digest("SHA-256", buffer);
|
|
1119
1119
|
const hashArray = Array.from(new Uint8Array(hashBuffer));
|
|
1120
1120
|
const hashHex = hashArray.map((b) => b.toString(16).padStart(2, "0")).join("");
|
|
1121
1121
|
return hashHex;
|
|
@@ -1257,8 +1257,8 @@ function rowToStop(row) {
|
|
|
1257
1257
|
return {
|
|
1258
1258
|
stop_id: String(row.stop_id),
|
|
1259
1259
|
stop_name: String(row.stop_name),
|
|
1260
|
-
stop_lat: Number(row.stop_lat),
|
|
1261
|
-
stop_lon: Number(row.stop_lon),
|
|
1260
|
+
stop_lat: row.stop_lat !== null ? Number(row.stop_lat) : void 0,
|
|
1261
|
+
stop_lon: row.stop_lon !== null ? Number(row.stop_lon) : void 0,
|
|
1262
1262
|
stop_code: row.stop_code ? String(row.stop_code) : void 0,
|
|
1263
1263
|
stop_desc: row.stop_desc ? String(row.stop_desc) : void 0,
|
|
1264
1264
|
zone_id: row.zone_id ? String(row.zone_id) : void 0,
|
|
@@ -1317,8 +1317,8 @@ function getRoutes(db, filters = {}) {
|
|
|
1317
1317
|
function rowToRoute(row) {
|
|
1318
1318
|
return {
|
|
1319
1319
|
route_id: String(row.route_id),
|
|
1320
|
-
route_short_name: String(row.route_short_name),
|
|
1321
|
-
route_long_name: String(row.route_long_name),
|
|
1320
|
+
route_short_name: row.route_short_name ? String(row.route_short_name) : void 0,
|
|
1321
|
+
route_long_name: row.route_long_name ? String(row.route_long_name) : void 0,
|
|
1322
1322
|
route_type: Number(row.route_type),
|
|
1323
1323
|
agency_id: row.agency_id ? String(row.agency_id) : void 0,
|
|
1324
1324
|
route_desc: row.route_desc ? String(row.route_desc) : void 0,
|
|
@@ -1810,7 +1810,7 @@ function buildOrderedStopList(db, tripIds) {
|
|
|
1810
1810
|
if (!tripStopSequences.has(tripId)) {
|
|
1811
1811
|
tripStopSequences.set(tripId, []);
|
|
1812
1812
|
}
|
|
1813
|
-
tripStopSequences.get(tripId)
|
|
1813
|
+
tripStopSequences.get(tripId)?.push({ stop_id: stopId, stop_sequence: stopSequence });
|
|
1814
1814
|
}
|
|
1815
1815
|
stmt.free();
|
|
1816
1816
|
const orderedStopIds = [];
|
|
@@ -1868,8 +1868,8 @@ function findInsertionPosition(orderedStopIds, newStopId, tripStops, currentInde
|
|
|
1868
1868
|
function rowToStopTime(row) {
|
|
1869
1869
|
return {
|
|
1870
1870
|
trip_id: String(row.trip_id),
|
|
1871
|
-
arrival_time: String(row.arrival_time),
|
|
1872
|
-
departure_time: String(row.departure_time),
|
|
1871
|
+
arrival_time: row.arrival_time ? String(row.arrival_time) : void 0,
|
|
1872
|
+
departure_time: row.departure_time ? String(row.departure_time) : void 0,
|
|
1873
1873
|
stop_id: String(row.stop_id),
|
|
1874
1874
|
stop_sequence: Number(row.stop_sequence),
|
|
1875
1875
|
stop_headsign: row.stop_headsign ? String(row.stop_headsign) : void 0,
|
|
@@ -2308,7 +2308,7 @@ function getTripUpdates(db, filters = {}, stalenessThreshold = 120) {
|
|
|
2308
2308
|
if (!stopTimesByTripId.has(stu.trip_id)) {
|
|
2309
2309
|
stopTimesByTripId.set(stu.trip_id, []);
|
|
2310
2310
|
}
|
|
2311
|
-
stopTimesByTripId.get(stu.trip_id)
|
|
2311
|
+
stopTimesByTripId.get(stu.trip_id)?.push(stu);
|
|
2312
2312
|
}
|
|
2313
2313
|
for (const tu of tripUpdates) {
|
|
2314
2314
|
tu.stop_time_update = stopTimesByTripId.get(tu.trip_id) || [];
|
|
@@ -2334,7 +2334,7 @@ function getAllTripUpdates(db) {
|
|
|
2334
2334
|
if (!stopTimesByTripId.has(stu.trip_id)) {
|
|
2335
2335
|
stopTimesByTripId.set(stu.trip_id, []);
|
|
2336
2336
|
}
|
|
2337
|
-
stopTimesByTripId.get(stu.trip_id)
|
|
2337
|
+
stopTimesByTripId.get(stu.trip_id)?.push(stu);
|
|
2338
2338
|
}
|
|
2339
2339
|
for (const tu of tripUpdates) {
|
|
2340
2340
|
tu.stop_time_update = stopTimesByTripId.get(tu.trip_id) || [];
|
|
@@ -2357,11 +2357,19 @@ var GtfsSqlJs = class _GtfsSqlJs {
|
|
|
2357
2357
|
this.lastRealtimeFetchTimestamp = null;
|
|
2358
2358
|
}
|
|
2359
2359
|
/**
|
|
2360
|
-
* Create GtfsSqlJs instance from GTFS ZIP file
|
|
2360
|
+
* Create GtfsSqlJs instance from GTFS ZIP file path or URL
|
|
2361
2361
|
*/
|
|
2362
2362
|
static async fromZip(zipPath, options = {}) {
|
|
2363
|
+
const zipData = await fetchZip(zipPath, options.onProgress);
|
|
2364
|
+
return _GtfsSqlJs.fromZipData(zipData, options, zipPath);
|
|
2365
|
+
}
|
|
2366
|
+
/**
|
|
2367
|
+
* Create GtfsSqlJs instance from pre-loaded GTFS ZIP data
|
|
2368
|
+
* @param source - Optional original path/URL, used for cache key generation and metadata
|
|
2369
|
+
*/
|
|
2370
|
+
static async fromZipData(zipData, options = {}, source) {
|
|
2363
2371
|
const instance = new _GtfsSqlJs();
|
|
2364
|
-
await instance.
|
|
2372
|
+
await instance.initFromZipData(zipData, options, source);
|
|
2365
2373
|
return instance;
|
|
2366
2374
|
}
|
|
2367
2375
|
/**
|
|
@@ -2373,9 +2381,10 @@ var GtfsSqlJs = class _GtfsSqlJs {
|
|
|
2373
2381
|
return instance;
|
|
2374
2382
|
}
|
|
2375
2383
|
/**
|
|
2376
|
-
* Initialize from ZIP
|
|
2384
|
+
* Initialize from pre-loaded ZIP data
|
|
2385
|
+
* @param source - Optional original path/URL, used for cache key generation and metadata
|
|
2377
2386
|
*/
|
|
2378
|
-
async
|
|
2387
|
+
async initFromZipData(zipData, options, source) {
|
|
2379
2388
|
const onProgress = options.onProgress;
|
|
2380
2389
|
const {
|
|
2381
2390
|
cache: userCache,
|
|
@@ -2396,20 +2405,14 @@ var GtfsSqlJs = class _GtfsSqlJs {
|
|
|
2396
2405
|
percentComplete: 0,
|
|
2397
2406
|
message: "Checking cache..."
|
|
2398
2407
|
});
|
|
2399
|
-
|
|
2400
|
-
|
|
2401
|
-
zipData2 = await fetchZip(zipPath, onProgress);
|
|
2402
|
-
} else {
|
|
2403
|
-
zipData2 = zipPath;
|
|
2404
|
-
}
|
|
2405
|
-
const filesize = zipData2.byteLength;
|
|
2406
|
-
const checksum = await computeZipChecksum(zipData2);
|
|
2408
|
+
const filesize = zipData.byteLength;
|
|
2409
|
+
const checksum = await computeZipChecksum(zipData);
|
|
2407
2410
|
const cacheKey = generateCacheKey(
|
|
2408
2411
|
checksum,
|
|
2409
2412
|
LIB_VERSION,
|
|
2410
2413
|
cacheVersion,
|
|
2411
2414
|
filesize,
|
|
2412
|
-
|
|
2415
|
+
source,
|
|
2413
2416
|
skipFiles
|
|
2414
2417
|
);
|
|
2415
2418
|
const cacheEntry = await cache.get(cacheKey);
|
|
@@ -2458,7 +2461,7 @@ var GtfsSqlJs = class _GtfsSqlJs {
|
|
|
2458
2461
|
return;
|
|
2459
2462
|
}
|
|
2460
2463
|
}
|
|
2461
|
-
await this.loadFromZipData(
|
|
2464
|
+
await this.loadFromZipData(zipData, options, onProgress);
|
|
2462
2465
|
onProgress?.({
|
|
2463
2466
|
phase: "saving_cache",
|
|
2464
2467
|
currentFile: null,
|
|
@@ -2474,7 +2477,7 @@ var GtfsSqlJs = class _GtfsSqlJs {
|
|
|
2474
2477
|
checksum,
|
|
2475
2478
|
version: cacheVersion,
|
|
2476
2479
|
timestamp: Date.now(),
|
|
2477
|
-
source
|
|
2480
|
+
source,
|
|
2478
2481
|
size: dbBuffer.byteLength,
|
|
2479
2482
|
skipFiles
|
|
2480
2483
|
});
|
|
@@ -2490,12 +2493,6 @@ var GtfsSqlJs = class _GtfsSqlJs {
|
|
|
2490
2493
|
});
|
|
2491
2494
|
return;
|
|
2492
2495
|
}
|
|
2493
|
-
let zipData;
|
|
2494
|
-
if (typeof zipPath === "string") {
|
|
2495
|
-
zipData = await fetchZip(zipPath, onProgress);
|
|
2496
|
-
} else {
|
|
2497
|
-
zipData = zipPath;
|
|
2498
|
-
}
|
|
2499
2496
|
await this.loadFromZipData(zipData, options, onProgress);
|
|
2500
2497
|
onProgress?.({
|
|
2501
2498
|
phase: "complete",
|
|
@@ -2509,10 +2506,13 @@ var GtfsSqlJs = class _GtfsSqlJs {
|
|
|
2509
2506
|
});
|
|
2510
2507
|
}
|
|
2511
2508
|
/**
|
|
2512
|
-
* Helper method to load GTFS data from zip data
|
|
2509
|
+
* Helper method to load GTFS data from zip data
|
|
2513
2510
|
* Used by both cache-enabled and cache-disabled paths
|
|
2514
2511
|
*/
|
|
2515
2512
|
async loadFromZipData(zipData, options, onProgress) {
|
|
2513
|
+
if (!this.SQL) {
|
|
2514
|
+
throw new Error("SQL.js not initialized");
|
|
2515
|
+
}
|
|
2516
2516
|
this.db = new this.SQL.Database();
|
|
2517
2517
|
this.db.run("PRAGMA synchronous = OFF");
|
|
2518
2518
|
this.db.run("PRAGMA journal_mode = MEMORY");
|
|
@@ -2544,7 +2544,7 @@ var GtfsSqlJs = class _GtfsSqlJs {
|
|
|
2544
2544
|
percentComplete: 35,
|
|
2545
2545
|
message: "Extracting GTFS ZIP file"
|
|
2546
2546
|
});
|
|
2547
|
-
const files = await loadGTFSZip(zipData);
|
|
2547
|
+
const files = await loadGTFSZip(zipData, options.skipFiles);
|
|
2548
2548
|
onProgress?.({
|
|
2549
2549
|
phase: "inserting_data",
|
|
2550
2550
|
currentFile: null,
|