react-listing-engine 0.6.4 → 0.6.6
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 +54 -65
- package/dist/chunk-OXSYNZAJ.js +2 -0
- package/dist/chunk-PE27NATS.cjs +2 -0
- package/dist/index.cjs +2 -2
- package/dist/index.d.cts +95 -16
- package/dist/index.d.ts +95 -16
- package/dist/index.js +1 -1
- package/dist/{listing-app-wmMuDlVU.d.ts → listing-app-4Vs_SMNl.d.cts} +146 -26
- package/dist/{listing-app-DJbvx3oe.d.cts → listing-app-CkEGdUV9.d.ts} +146 -26
- package/dist/map-provider.interface-DT-v1plm.d.cts +67 -0
- package/dist/map-provider.interface-DT-v1plm.d.ts +67 -0
- package/dist/maps/google/index.d.cts +1 -2
- package/dist/maps/google/index.d.ts +1 -2
- package/dist/styled/index.cjs +1 -1
- package/dist/styled/index.d.cts +7 -10
- package/dist/styled/index.d.ts +7 -10
- package/dist/styled/index.js +1 -1
- package/dist/testing/index.d.cts +1 -2
- package/dist/testing/index.d.ts +1 -2
- package/package.json +3 -14
- package/dist/chunk-2VUHLHHX.cjs +0 -2
- package/dist/chunk-35KYEBAC.js +0 -2
- package/dist/chunk-5FBI2WIM.js +0 -2
- package/dist/chunk-6PZHSHU3.js +0 -2
- package/dist/chunk-CGT3RHJ7.js +0 -2
- package/dist/chunk-CHNUE46K.cjs +0 -2
- package/dist/chunk-EYXV5OMY.cjs +0 -2
- package/dist/chunk-LCQZIWBO.cjs +0 -2
- package/dist/chunk-R3FX2V3N.js +0 -2
- package/dist/chunk-RXHR66FS.cjs +0 -2
- package/dist/components-provider-CF0Mo0B8.d.cts +0 -120
- package/dist/components-provider-CjMxkxrP.d.ts +0 -120
- package/dist/entity-adapter.interface-BDgbSxhq.d.cts +0 -33
- package/dist/entity-adapter.interface-BDgbSxhq.d.ts +0 -33
- package/dist/listing-config-options.interface-ZJYY_ZvR.d.cts +0 -12
- package/dist/listing-config-options.interface-ZJYY_ZvR.d.ts +0 -12
- package/dist/map-provider.interface-BMnwW3ob.d.cts +0 -37
- package/dist/map-provider.interface-BxexMT3X.d.ts +0 -37
- package/dist/presets/rental/index.cjs +0 -2
- package/dist/presets/rental/index.d.cts +0 -266
- package/dist/presets/rental/index.d.ts +0 -266
- package/dist/presets/rental/index.js +0 -2
- package/dist/shadcn/index.cjs +0 -2
- package/dist/shadcn/index.d.cts +0 -261
- package/dist/shadcn/index.d.ts +0 -261
- package/dist/shadcn/index.js +0 -2
- package/dist/url-sync.controller-CsU_QxoS.d.cts +0 -89
- package/dist/url-sync.controller-DX67JivW.d.ts +0 -89
|
@@ -1,89 +0,0 @@
|
|
|
1
|
-
import { Q as QueryParams } from './entity-adapter.interface-BDgbSxhq.js';
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* DOM-agnostic abstraction over "the URL's query string" — or, in tests/SSR,
|
|
5
|
-
* an in-memory stand-in (`MemoryHistoryPort`). `UrlSyncController` talks to
|
|
6
|
-
* this interface only, never to `window.location`/`history` directly, so it
|
|
7
|
-
* stays framework- and environment-free like the rest of `src/core`.
|
|
8
|
-
*/
|
|
9
|
-
interface HistoryPort {
|
|
10
|
-
getQuery(): QueryParams;
|
|
11
|
-
setQuery(params: QueryParams): void;
|
|
12
|
-
subscribe(cb: () => void): () => void;
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
interface UrlSyncEngine<TFilters> {
|
|
16
|
-
subscribe(cb: () => void): () => void;
|
|
17
|
-
readonly state: {
|
|
18
|
-
readonly filters: TFilters;
|
|
19
|
-
};
|
|
20
|
-
applyFilters(patch: Partial<TFilters>): Promise<void> | void;
|
|
21
|
-
}
|
|
22
|
-
interface UrlSyncOptions<TFilters> {
|
|
23
|
-
history: HistoryPort;
|
|
24
|
-
toQuery(filters: TFilters): QueryParams;
|
|
25
|
-
toFilters(query: QueryParams): Partial<TFilters>;
|
|
26
|
-
hydrateOnStart?: boolean;
|
|
27
|
-
}
|
|
28
|
-
/**
|
|
29
|
-
* Bidirectional, DOM-agnostic sync between an engine's `filters` and a
|
|
30
|
-
* `HistoryPort`'s query params. Framework-free: talks to `UrlSyncEngine`
|
|
31
|
-
* (a structural subset `ListingEngine` satisfies) and `HistoryPort`, nothing
|
|
32
|
-
* else — no `window`, no React.
|
|
33
|
-
*
|
|
34
|
-
* OPTIONAL, not the primary path: `styled/listing-app.tsx`'s turnkey
|
|
35
|
-
* `ListingApp` (the package's main-entry default) does NOT wire this up —
|
|
36
|
-
* it uses an event-based URL API instead (`initialFilters` in,
|
|
37
|
-
* `onFiltersChange` out; see that file's doc comment), so the library never
|
|
38
|
-
* touches `window.history` by default. This class remains exported for
|
|
39
|
-
* consumers who explicitly want the library to own history writes/reads
|
|
40
|
-
* itself (e.g. via `/shadcn`'s `ListingApp.urlSync`, or wiring it directly
|
|
41
|
-
* against a hand-built engine).
|
|
42
|
-
*
|
|
43
|
-
* Echo-loop guard: both subscriptions below are driven by the SAME
|
|
44
|
-
* `isSyncing` flag. `ListingEngine.applyFilters()` and `MemoryHistoryPort`
|
|
45
|
-
* (and any real browser HistoryPort) both notify their subscribers
|
|
46
|
-
* SYNCHRONOUSLY as part of the write (`store.setFilters()` -> `notify()`
|
|
47
|
-
* happens before any debounce timer, and `MemoryHistoryPort.setQuery()`
|
|
48
|
-
* notifies before returning) — so when this controller initiates a write on
|
|
49
|
-
* one side, the reciprocal subscription on the other side fires within the
|
|
50
|
-
* very same call stack, before `isSyncing` is reset. Wrapping each
|
|
51
|
-
* controller-initiated write in `isSyncing = true; ...; isSyncing = false`
|
|
52
|
-
* (via try/finally, so a throwing `toQuery`/`toFilters`/notify can't leave it
|
|
53
|
-
* stuck) means that reciprocal callback observes `isSyncing === true` and
|
|
54
|
-
* short-circuits instead of writing back — one hop each direction, never a
|
|
55
|
-
* cascade. `hydrateOnStart`'s initial engine write is wrapped the same way,
|
|
56
|
-
* since it must not immediately echo the just-hydrated filters back out to
|
|
57
|
-
* history as a redundant `setQuery`.
|
|
58
|
-
*
|
|
59
|
-
* `isSyncing` only covers that SYNCHRONOUS window, though — the real
|
|
60
|
-
* `ListingEngine.applyFilters()` notifies AGAIN, asynchronously: after
|
|
61
|
-
* `await adapter.list(...)` resolves, `store.setResults()` and
|
|
62
|
-
* `store.setLoading(false)` each call `notify()`, well after `isSyncing` has
|
|
63
|
-
* already been reset to `false` by the `withSyncGuard` that kicked the query
|
|
64
|
-
* off. Left unguarded, that async tail would fire the engine subscription
|
|
65
|
-
* below and echo an identical (but spurious) `history.setQuery(...)` on
|
|
66
|
-
* every completed query. Rather than widening `isSyncing` to cover the whole
|
|
67
|
-
* async query (which would also swallow legitimate concurrent history
|
|
68
|
-
* changes that land mid-query), `syncEngineToHistory` is idempotent BY
|
|
69
|
-
* VALUE instead: it computes the target query and skips the write entirely
|
|
70
|
-
* when it already matches `history.getQuery()` — timing-independent, so it
|
|
71
|
-
* suppresses the async-tail echo without touching `isSyncing` at all.
|
|
72
|
-
*/
|
|
73
|
-
declare class UrlSyncController<TFilters> {
|
|
74
|
-
private readonly history;
|
|
75
|
-
private readonly toQueryFn;
|
|
76
|
-
private readonly toFiltersFn;
|
|
77
|
-
private readonly hydrateOnStart;
|
|
78
|
-
private isSyncing;
|
|
79
|
-
private unsubscribeEngine;
|
|
80
|
-
private unsubscribeHistory;
|
|
81
|
-
constructor(opts: UrlSyncOptions<TFilters>);
|
|
82
|
-
start(engine: UrlSyncEngine<TFilters>): void;
|
|
83
|
-
stop(): void;
|
|
84
|
-
private syncEngineToHistory;
|
|
85
|
-
private applyFiltersSafely;
|
|
86
|
-
private withSyncGuard;
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
export { type HistoryPort as H, UrlSyncController as U, type UrlSyncEngine as a, type UrlSyncOptions as b };
|