gtfs-garage-web 0.0.3 → 0.1.0
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 +29 -19
- package/dist/dataset.js +1 -1
- package/dist/{mount-CHJb5mxA.js → mount-EvMk5jp_.js} +6 -6
- package/dist/mount.d.ts +10 -0
- package/dist/mount.js +1 -1
- package/dist/react.js +1 -1
- package/dist/schema.d.ts +2 -2
- package/dist/sources/api.gen.d.ts +987 -0
- package/dist/sources/types.d.ts +37 -215
- package/package.json +4 -2
package/README.md
CHANGED
|
@@ -9,19 +9,12 @@ be mounted in another application.
|
|
|
9
9
|
|
|
10
10
|
```sh
|
|
11
11
|
npm install gtfs-garage-web
|
|
12
|
-
```
|
|
13
|
-
|
|
14
|
-
The map is a separate entry point, and MapLibre an **optional** peer. Install
|
|
15
|
-
it only if you want one:
|
|
16
|
-
|
|
17
|
-
```sh
|
|
18
12
|
npm install maplibre-gl # only with the map
|
|
19
13
|
```
|
|
20
14
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
not the branch runs, so a flag would still have made MapLibre mandatory.
|
|
15
|
+
ESM only — a bundler or native ES modules, no `<script>` drop-in. MapLibre is an
|
|
16
|
+
**optional** peer behind its own entry point, so a viewer without a map neither
|
|
17
|
+
downloads it nor needs it installed to build.
|
|
25
18
|
|
|
26
19
|
## React
|
|
27
20
|
|
|
@@ -35,14 +28,10 @@ import "maplibre-gl/dist/maplibre-gl.css";
|
|
|
35
28
|
|
|
36
29
|
export default function Feed() {
|
|
37
30
|
return <GtfsGarage map={mapPart} baseUrl="https://example.org" style={{ height: "80vh" }} />;
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
Drop the two `map` imports and the MapLibre stylesheet for a table-only viewer:
|
|
41
|
-
|
|
42
|
-
```tsx
|
|
43
|
-
<GtfsGarage baseUrl="https://example.org" style={{ height: "80vh" }} />
|
|
31
|
+
}
|
|
44
32
|
```
|
|
45
33
|
|
|
34
|
+
Drop the two `map` imports and the MapLibre stylesheet for a table-only viewer.
|
|
46
35
|
`"use client"` is required: the viewer builds DOM and cannot render on a server.
|
|
47
36
|
|
|
48
37
|
**Give the container a height.** The viewer fills whatever box it is given, and
|
|
@@ -62,12 +51,25 @@ const viewer = await mount(document.querySelector("#feed")!, {
|
|
|
62
51
|
viewer.destroy(); // releases the map, the history subscription and the markup
|
|
63
52
|
```
|
|
64
53
|
|
|
54
|
+
## A dataset that is still being prepared
|
|
55
|
+
|
|
56
|
+
`GtfsGarageDataset` waits for one, and draws the being-prepared, not-prepared
|
|
57
|
+
and failed states itself — so no host writes a progress bar:
|
|
58
|
+
|
|
59
|
+
```tsx
|
|
60
|
+
import { GtfsGarageDataset } from "gtfs-garage-web/react";
|
|
61
|
+
|
|
62
|
+
<GtfsGarageDataset dataset={provider} description="mdb-1210" style={{ height: "80vh" }} />
|
|
63
|
+
```
|
|
64
|
+
|
|
65
65
|
## Where the data comes from
|
|
66
66
|
|
|
67
67
|
By default the viewer talks to a GTFS Garage server at `baseUrl`. To drive it
|
|
68
|
-
from your own backend
|
|
69
|
-
`
|
|
70
|
-
|
|
68
|
+
from your own backend, either serve the same API — specified in
|
|
69
|
+
[`docs/GtfsGarageAPI.yaml`](https://github.com/MobilityData/gtfs-garage/blob/main/docs/GtfsGarageAPI.yaml)
|
|
70
|
+
— or pass a `source` implementing `ViewerSource`, which is the escape hatch for
|
|
71
|
+
a backend of any other shape, for authentication, or for reading Parquet in the
|
|
72
|
+
browser with no server at all.
|
|
71
73
|
|
|
72
74
|
## Styling
|
|
73
75
|
|
|
@@ -81,6 +83,14 @@ page. The design tokens are declared on that class and are the theming API:
|
|
|
81
83
|
}
|
|
82
84
|
```
|
|
83
85
|
|
|
86
|
+
## Documentation
|
|
87
|
+
|
|
88
|
+
**[Embedding the viewer](https://github.com/MobilityData/gtfs-garage/blob/main/docs/INTEGRATION.md)**
|
|
89
|
+
— every option, the three ways to supply data, what your server has to provide
|
|
90
|
+
(including CORS and authentication, which the API document deliberately leaves
|
|
91
|
+
to you), the dataset-preparation lifecycle, and a worked adapter for driving the
|
|
92
|
+
viewer from an API of your own.
|
|
93
|
+
|
|
84
94
|
## Licence
|
|
85
95
|
|
|
86
96
|
Apache-2.0
|
package/dist/dataset.js
CHANGED
|
@@ -295,7 +295,7 @@ function ie(n) {
|
|
|
295
295
|
e.push([se[n.kind], `${p(n.acquire_ms)}${t}`]);
|
|
296
296
|
}
|
|
297
297
|
if (n.extract_ms != null && e.push(["Unzip", `${p(n.extract_ms)} · ${f(n.total_bytes)} archive`]), n.register_ms != null && e.push(["Read headers", p(n.register_ms)]), n.convert_ms != null) {
|
|
298
|
-
const t = n.stored_bytes
|
|
298
|
+
const t = n.stored_bytes == null ? "" : ` · ${f(n.stored_bytes)} stored`;
|
|
299
299
|
e.push(["Convert to Parquet", `${p(n.convert_ms)}${t}`]);
|
|
300
300
|
}
|
|
301
301
|
return n.count_ms != null && e.push(["Count rows", p(n.count_ms)]), e;
|
|
@@ -306,19 +306,19 @@ function le(n) {
|
|
|
306
306
|
name: t.name,
|
|
307
307
|
bytes: f(t.bytes),
|
|
308
308
|
share: e === 0 ? 0 : Math.round(t.bytes / e * 100),
|
|
309
|
-
compressed: t.compressed_bytes
|
|
310
|
-
stored: t.parquet_bytes
|
|
309
|
+
compressed: t.compressed_bytes == null ? "—" : f(t.compressed_bytes),
|
|
310
|
+
stored: t.parquet_bytes == null ? "—" : f(t.parquet_bytes),
|
|
311
311
|
costMs: re(n, t),
|
|
312
|
-
rows: t.row_count
|
|
312
|
+
rows: t.row_count == null ? "—" : t.row_count.toLocaleString(),
|
|
313
313
|
columns: t.columns
|
|
314
314
|
}));
|
|
315
315
|
}
|
|
316
316
|
function O(n) {
|
|
317
|
-
return n.convert_ms
|
|
317
|
+
return n.convert_ms != null;
|
|
318
318
|
}
|
|
319
319
|
function re(n, e) {
|
|
320
320
|
const t = O(n) ? e.convert_ms : e.count_ms;
|
|
321
|
-
return t
|
|
321
|
+
return t == null ? "—" : p(t);
|
|
322
322
|
}
|
|
323
323
|
function de(n) {
|
|
324
324
|
const e = n.phases ? null : O(n) ? {
|
package/dist/mount.d.ts
CHANGED
|
@@ -14,6 +14,16 @@ import { type AppState } from "./state";
|
|
|
14
14
|
import { type HistoryPort } from "./ui/history";
|
|
15
15
|
export type { ViewerParts } from "./markup";
|
|
16
16
|
export type { GtfsSource, ViewerSource } from "./sources/types";
|
|
17
|
+
/**
|
|
18
|
+
* The payload types, re-exported so a host implementing `ViewerSource` can name
|
|
19
|
+
* what its methods return. They are generated from `docs/GtfsGarageAPI.yaml`,
|
|
20
|
+
* so an implementation written against them is checked against the contract at
|
|
21
|
+
* compile time - which is the whole point of generating them, and is worth
|
|
22
|
+
* nothing if they stop at the package boundary.
|
|
23
|
+
*/
|
|
24
|
+
export type { AppConfig, ColumnInfo, ConditionOutcome, DatasetManifest, FeatureCollection, FileCondition, FileMetrics, Filter, FilterOperator, GeoFeature, GeoJsonKind, ImpliedValue, LoadMetrics, LoadProgress, MissingFile, PageResponse, RelatedLink, Row, TableInfo, TablesResponse, ValueCount, } from "./sources/types";
|
|
25
|
+
/** `geojsonStream` hands these to its callback, so an implementer names them too. */
|
|
26
|
+
export type { NdjsonMessage } from "./sources/ndjson";
|
|
17
27
|
export { RestSource } from "./sources/rest";
|
|
18
28
|
export { browserHistory, memoryHistory, type HistoryPort } from "./ui/history";
|
|
19
29
|
export interface ViewerOptions {
|
package/dist/mount.js
CHANGED
package/dist/react.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { jsx as f } from "react/jsx-runtime";
|
|
2
2
|
import { useRef as c, useEffect as i } from "react";
|
|
3
3
|
import { mountDataset as m } from "./dataset.js";
|
|
4
|
-
import { m as d } from "./mount-
|
|
4
|
+
import { m as d } from "./mount-EvMk5jp_.js";
|
|
5
5
|
function p({ className: l, style: u, ...e }) {
|
|
6
6
|
const o = c(null), n = c(e);
|
|
7
7
|
return n.current = e, i(() => {
|
package/dist/schema.d.ts
CHANGED
|
@@ -10,9 +10,9 @@ import type { ColumnInfo, MissingFile } from "./sources/types";
|
|
|
10
10
|
interface Field {
|
|
11
11
|
type?: string;
|
|
12
12
|
values?: Record<string, string>;
|
|
13
|
-
required?:
|
|
13
|
+
required?: ColumnInfo["required"];
|
|
14
14
|
condition?: string;
|
|
15
|
-
conditionScope?:
|
|
15
|
+
conditionScope?: ColumnInfo["condition_scope"];
|
|
16
16
|
primaryKey?: boolean;
|
|
17
17
|
references?: {
|
|
18
18
|
table: string;
|