@sylwellsoftware/glue 0.2.0 → 0.4.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 +108 -11
- package/dist/commands/asyncCommand.d.ts +1 -1
- package/dist/commands/asyncCommand.d.ts.map +1 -1
- package/dist/emitters/liveQuery.d.ts +21 -1
- package/dist/emitters/liveQuery.d.ts.map +1 -1
- package/dist/emitters/liveResult.d.ts +14 -0
- package/dist/emitters/liveResult.d.ts.map +1 -0
- package/dist/index.d.ts +7 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +760 -110
- package/dist/index.js.map +1 -1
- package/dist/queryhandling/endpoints.d.ts +77 -0
- package/dist/queryhandling/endpoints.d.ts.map +1 -0
- package/dist/queryhandling/restQueryHandler.d.ts +3 -0
- package/dist/queryhandling/restQueryHandler.d.ts.map +1 -1
- package/package.json +2 -7
- package/EXPERIMENTAL.md +0 -44
- package/dist/emitter-upM7NC28.js +0 -293
- package/dist/emitter-upM7NC28.js.map +0 -1
- package/dist/experimental.d.ts +0 -7
- package/dist/experimental.d.ts.map +0 -1
- package/dist/experimental.js +0 -151
- package/dist/experimental.js.map +0 -1
package/README.md
CHANGED
|
@@ -5,7 +5,7 @@ uses it as its state/data-flow layer, but Glue does not depend on Fray, a DOM,
|
|
|
5
5
|
or any UI framework. Its implementation and tests are strict TypeScript; the
|
|
6
6
|
ESM build includes declarations and declaration maps.
|
|
7
7
|
|
|
8
|
-
Install
|
|
8
|
+
Install with pnpm:
|
|
9
9
|
|
|
10
10
|
```bash
|
|
11
11
|
pnpm add @sylwellsoftware/glue
|
|
@@ -46,8 +46,13 @@ by asynchronous retrieval. Richer responsibilities remain separate:
|
|
|
46
46
|
| `DerivedEmitter` | A cached value computed from one or more readable emitters |
|
|
47
47
|
| `QueryArg` | A named query-input view over another emitter when a semantic name is useful |
|
|
48
48
|
| `LiveQuery` | Reactive request timing, latest-request ownership, status/error state, and cached results |
|
|
49
|
+
| `LiveResult` | Common read/dispose contract for remote and locally derived endpoint results |
|
|
49
50
|
| `QueryHandler` | Non-reactive retrieval strategy over a plain named argument object |
|
|
50
51
|
| `RestQueryHandler` | HTTP URL construction, wire serialization, Fetch execution, and JSON result retrieval |
|
|
52
|
+
| `QueryEndpoint` | Immutable declaration that opens caller-owned queries through any handler |
|
|
53
|
+
| `RestEndpoint` | Immutable REST query declaration with optional response parsing |
|
|
54
|
+
| `DerivedEndpoint` | Immutable local projection declaration that opens caller-owned live results |
|
|
55
|
+
| `AsyncCommand` | Abortable mutation lifecycle with explicit concurrency policy |
|
|
51
56
|
| `EventBubble` / `EventBus` | Optional cause-and-effect diagnostics without owning application history |
|
|
52
57
|
|
|
53
58
|
The intended flow is explicit and one-directional:
|
|
@@ -177,20 +182,104 @@ const users = new LiveQuery({handler, args: {search}})
|
|
|
177
182
|
Arguments are a named record of emitters. Construction fetches immediately
|
|
178
183
|
unless `autoFetch: false`; `refresh()` and `retry()` return the active request
|
|
179
184
|
promise. A newer request aborts and supersedes the older request, and stale
|
|
180
|
-
results cannot overwrite current state. `
|
|
181
|
-
and releases argument subscriptions.
|
|
185
|
+
results cannot overwrite current state. `abort()` cancels without disposing;
|
|
186
|
+
`dispose()` aborts the active request and releases argument subscriptions.
|
|
182
187
|
|
|
183
188
|
By default the last successful value remains visible while refreshing and after
|
|
184
189
|
a refresh error. Set `keepPreviousValue: false` to clear it while loading or in
|
|
185
190
|
error state.
|
|
186
191
|
|
|
192
|
+
Polling is opt-in and waits one full interval before the first poll:
|
|
193
|
+
|
|
194
|
+
```ts
|
|
195
|
+
const pollingEnabled = new Emitter(true)
|
|
196
|
+
const intervalMs = new Emitter(5_000)
|
|
197
|
+
const users = new LiveQuery({
|
|
198
|
+
handler,
|
|
199
|
+
args: {search},
|
|
200
|
+
polling: {enabled: pollingEnabled, intervalMs},
|
|
201
|
+
})
|
|
202
|
+
```
|
|
203
|
+
|
|
204
|
+
`enabled` and `intervalMs` may be constants or readable emitters. A changed
|
|
205
|
+
control restarts the timer from that change. A tick is skipped while a request
|
|
206
|
+
is active; the next normal tick remains scheduled. Errors do not cause an
|
|
207
|
+
immediate retry or backoff, but polling continues while enabled. Disposal
|
|
208
|
+
releases the timer and control subscriptions. Applications can feed page
|
|
209
|
+
visibility or any other policy into `enabled`; Glue never reads the DOM. Tests
|
|
210
|
+
and nonstandard runtimes may inject `PollingScheduler`.
|
|
211
|
+
|
|
187
212
|
The REST adapter accepts injected `fetch`, `baseUrl`, and `serialize` behavior.
|
|
188
213
|
Its generic serializer omits `undefined` and empty arrays, encodes `null` as an
|
|
189
214
|
empty value, repeats keys for arrays, JSON-encodes objects, and stringifies
|
|
190
215
|
scalars. Application-specific table filter/sort formats belong in an injected
|
|
191
|
-
serializer, not Glue. A
|
|
192
|
-
|
|
193
|
-
the
|
|
216
|
+
serializer, not Glue. A result generic alone does not validate JSON. Supply
|
|
217
|
+
`parseResult(json: unknown)` to decode or validate immediately after JSON
|
|
218
|
+
parsing. A thrown parser error becomes the `LiveQuery` error, and Glue does not
|
|
219
|
+
include the raw response body in its diagnostics.
|
|
220
|
+
|
|
221
|
+
## Service endpoint declarations
|
|
222
|
+
|
|
223
|
+
Applications may group immutable endpoint declarations in ordinary service
|
|
224
|
+
classes. Glue does not register, locate, construct, or cache services; the
|
|
225
|
+
application chooses and constructs its service scope. Fray applications may
|
|
226
|
+
expose those services through Fray's typed runtime `ServiceScope`; non-Fray
|
|
227
|
+
applications use their own explicit composition. Every `open()` call creates a
|
|
228
|
+
caller-owned result with independent arguments, request state, polling, and
|
|
229
|
+
disposal.
|
|
230
|
+
|
|
231
|
+
```ts
|
|
232
|
+
import {DerivedEndpoint, RestEndpoint} from '@sylwellsoftware/glue'
|
|
233
|
+
|
|
234
|
+
class MovieService {
|
|
235
|
+
readonly movies = new RestEndpoint<{genre: string}, readonly Movie[]>({
|
|
236
|
+
url: '/api/movies',
|
|
237
|
+
parseResult: parseMovies,
|
|
238
|
+
})
|
|
239
|
+
|
|
240
|
+
readonly matchingMovies = new DerivedEndpoint<
|
|
241
|
+
readonly Movie[],
|
|
242
|
+
{genre: string},
|
|
243
|
+
readonly Movie[]
|
|
244
|
+
>({
|
|
245
|
+
apply: (movies, {genre}) => movies.filter((movie) => movie.genre === genre),
|
|
246
|
+
})
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
const service = new MovieService()
|
|
250
|
+
const remote = service.movies.open({genre})
|
|
251
|
+
const local = service.matchingMovies.open({source: cachedMovies, args: {genre}})
|
|
252
|
+
```
|
|
253
|
+
|
|
254
|
+
Both results implement `LiveResult`, so a UI that only reads value, fetch
|
|
255
|
+
state, error, and subscriptions can accept either. `LiveQuery` additionally
|
|
256
|
+
implements `RefreshableLiveResult` with `refresh()`, `retry()`, and `abort()`.
|
|
257
|
+
|
|
258
|
+
For a query-like body protocol such as GraphQL, put a custom handler in a
|
|
259
|
+
`QueryEndpoint`. The handler owns method, headers, authentication, body
|
|
260
|
+
serialization, response checks, validation, and safe diagnostics:
|
|
261
|
+
|
|
262
|
+
```ts
|
|
263
|
+
import {QueryEndpoint} from '@sylwellsoftware/glue'
|
|
264
|
+
|
|
265
|
+
const projectStatus = new QueryEndpoint<{id: string}, ProjectStatus>({
|
|
266
|
+
handler: {
|
|
267
|
+
async fetch({id}, {signal} = {}) {
|
|
268
|
+
const response = await fetch('/graphql', {
|
|
269
|
+
method: 'POST',
|
|
270
|
+
headers: {'content-type': 'application/json'},
|
|
271
|
+
body: JSON.stringify({query: STATUS_QUERY, variables: {id}}),
|
|
272
|
+
signal,
|
|
273
|
+
})
|
|
274
|
+
if (!response.ok) throw new Error(`HTTP ${response.status}`)
|
|
275
|
+
return parseProjectStatus(await response.json())
|
|
276
|
+
},
|
|
277
|
+
},
|
|
278
|
+
})
|
|
279
|
+
```
|
|
280
|
+
|
|
281
|
+
Ordinary POST/PUT/PATCH/DELETE mutations belong in `AsyncCommand` executors,
|
|
282
|
+
not auto-running query declarations.
|
|
194
283
|
|
|
195
284
|
## Optional tracing
|
|
196
285
|
|
|
@@ -206,14 +295,22 @@ start, and query completion can retain explicit parent/child causality without
|
|
|
206
295
|
turning diagnostics into a second execution system. Applications decide
|
|
207
296
|
whether to retain, render, or export observed events.
|
|
208
297
|
|
|
209
|
-
##
|
|
298
|
+
## Async commands
|
|
210
299
|
|
|
211
|
-
|
|
300
|
+
`AsyncCommand` is exported from Glue's package root. It is an abortable
|
|
212
301
|
mutation lifecycle with explicit `ignore`, `replace`, and `reject` concurrency
|
|
213
302
|
policies. It exposes the last result/error through the standard emitter
|
|
214
303
|
snapshot and a read-only `isRunning` view. It deliberately does not own batch
|
|
215
|
-
progress, retries, notifications, or UI behavior.
|
|
216
|
-
|
|
304
|
+
progress, retries, notifications, or UI behavior. Executor completion alone
|
|
305
|
+
determines command success. The application may then refresh affected queries;
|
|
306
|
+
their failures remain in their own query snapshots:
|
|
307
|
+
|
|
308
|
+
```ts
|
|
309
|
+
const saved = await saveCommand.run(update)
|
|
310
|
+
if (saved !== undefined) {
|
|
311
|
+
await Promise.all([users.refresh('save reconciled'), audit.refresh('save reconciled')])
|
|
312
|
+
}
|
|
313
|
+
```
|
|
217
314
|
|
|
218
315
|
## Integration with Fray and other consumers
|
|
219
316
|
|
|
@@ -256,7 +353,7 @@ Glue intentionally does not own a DOM renderer, component lifecycle,
|
|
|
256
353
|
application-specific query encoding, persistent event history, CommonJS build,
|
|
257
354
|
or framework adapter. Fray consumes Glue as a peer; browser UI belongs there.
|
|
258
355
|
|
|
259
|
-
See the [workspace overview](../../README.md), [
|
|
356
|
+
See the [workspace overview](../../README.md), [API
|
|
260
357
|
surface](../../docs/API_SURFACE.md), [changelog](../../CHANGELOG.md),
|
|
261
358
|
[contribution guide](../../CONTRIBUTING.md), and [security
|
|
262
359
|
policy](../../SECURITY.md).
|
|
@@ -19,7 +19,7 @@ export interface AsyncCommandOptions<TArguments, TResult, TError = unknown> {
|
|
|
19
19
|
export declare class AsyncCommandConcurrencyError extends Error {
|
|
20
20
|
constructor();
|
|
21
21
|
}
|
|
22
|
-
/**
|
|
22
|
+
/** Abortable mutation state with an explicit concurrency policy. */
|
|
23
23
|
export declare class AsyncCommand<TArguments, TResult, TError = unknown> extends BaseEmitter<TResult | undefined, TError> {
|
|
24
24
|
readonly execute: AsyncCommandExecutor<TArguments, TResult>;
|
|
25
25
|
readonly concurrency: AsyncCommandConcurrency;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"asyncCommand.d.ts","sourceRoot":"","sources":["../../src/commands/asyncCommand.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,WAAW,EAAC,MAAM,6BAA6B,CAAA;AACvD,OAAO,EAAC,WAAW,EAAC,MAAM,4BAA4B,CAAA;AACtD,OAAO,KAAK,EAAC,eAAe,EAAC,MAAM,4BAA4B,CAAA;AAG/D,OAAO,KAAK,EAAC,eAAe,EAAC,MAAM,kCAAkC,CAAA;AAErE,MAAM,MAAM,uBAAuB,GAAG,QAAQ,GAAG,SAAS,GAAG,QAAQ,CAAA;AAErE,MAAM,WAAW,mBAAmB;IAChC,QAAQ,CAAC,MAAM,EAAE,eAAe,CAAA;IAChC,QAAQ,CAAC,KAAK,EAAE,WAAW,CAAC,OAAO,CAAC,GAAG,IAAI,CAAA;CAC9C;AAED,MAAM,MAAM,oBAAoB,CAAC,UAAU,EAAE,OAAO,IAAI,CACpD,UAAU,EAAE,UAAU,EACtB,OAAO,EAAE,mBAAmB,KAC3B,OAAO,GAAG,WAAW,CAAC,OAAO,CAAC,CAAA;AAEnC,MAAM,WAAW,mBAAmB,CAAC,UAAU,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO;IACtE,OAAO,EAAE,oBAAoB,CAAC,UAAU,EAAE,OAAO,CAAC,CAAA;IAClD,WAAW,CAAC,EAAE,uBAAuB,CAAA;IACrC,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,MAAM,CAAA;IACrC,KAAK,CAAC,EAAE,OAAO,CAAA;IACf,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,KAAK,CAAC,EAAE,OAAO,CAAA;CAClB;AAWD,qBAAa,4BAA6B,SAAQ,KAAK;;CAKtD;AAED,
|
|
1
|
+
{"version":3,"file":"asyncCommand.d.ts","sourceRoot":"","sources":["../../src/commands/asyncCommand.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,WAAW,EAAC,MAAM,6BAA6B,CAAA;AACvD,OAAO,EAAC,WAAW,EAAC,MAAM,4BAA4B,CAAA;AACtD,OAAO,KAAK,EAAC,eAAe,EAAC,MAAM,4BAA4B,CAAA;AAG/D,OAAO,KAAK,EAAC,eAAe,EAAC,MAAM,kCAAkC,CAAA;AAErE,MAAM,MAAM,uBAAuB,GAAG,QAAQ,GAAG,SAAS,GAAG,QAAQ,CAAA;AAErE,MAAM,WAAW,mBAAmB;IAChC,QAAQ,CAAC,MAAM,EAAE,eAAe,CAAA;IAChC,QAAQ,CAAC,KAAK,EAAE,WAAW,CAAC,OAAO,CAAC,GAAG,IAAI,CAAA;CAC9C;AAED,MAAM,MAAM,oBAAoB,CAAC,UAAU,EAAE,OAAO,IAAI,CACpD,UAAU,EAAE,UAAU,EACtB,OAAO,EAAE,mBAAmB,KAC3B,OAAO,GAAG,WAAW,CAAC,OAAO,CAAC,CAAA;AAEnC,MAAM,WAAW,mBAAmB,CAAC,UAAU,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO;IACtE,OAAO,EAAE,oBAAoB,CAAC,UAAU,EAAE,OAAO,CAAC,CAAA;IAClD,WAAW,CAAC,EAAE,uBAAuB,CAAA;IACrC,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,MAAM,CAAA;IACrC,KAAK,CAAC,EAAE,OAAO,CAAA;IACf,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,KAAK,CAAC,EAAE,OAAO,CAAA;CAClB;AAWD,qBAAa,4BAA6B,SAAQ,KAAK;;CAKtD;AAED,oEAAoE;AACpE,qBAAa,YAAY,CAAC,UAAU,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAC3D,SAAQ,WAAW,CAAC,OAAO,GAAG,SAAS,EAAE,MAAM,CAAC;IAChD,QAAQ,CAAC,OAAO,EAAE,oBAAoB,CAAC,UAAU,EAAE,OAAO,CAAC,CAAA;IAC3D,QAAQ,CAAC,WAAW,EAAE,uBAAuB,CAAA;IAC7C,QAAQ,CAAC,SAAS,EAAE,eAAe,CAAC,OAAO,EAAE,KAAK,CAAC,CAAA;IACnD,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAA4B;IACrD,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAyB;IACxD,OAAO,CAAC,SAAS,CAAI;IACrB,OAAO,CAAC,eAAe,CAAmC;IAC1D,OAAO,CAAC,mBAAmB,CAAqB;IAChD,OAAO,CAAC,kBAAkB,CAAQ;IAClC,2EAA2E;IAC3E,cAAc,EAAE,OAAO,CAAC,OAAO,GAAG,SAAS,CAAC,GAAG,IAAI,CAAO;gBAE9C,OAAO,EAAE,mBAAmB,CAAC,UAAU,EAAE,OAAO,EAAE,MAAM,CAAC;IAgCrE,GAAG,CACC,UAAU,EAAE,UAAU,EACtB,YAAY,GAAE,WAAW,CAAC,OAAO,CAAC,GAAG,OAAuB,GAC7D,OAAO,CAAC,OAAO,GAAG,SAAS,CAAC;IAiE/B,KAAK,CAAC,YAAY,GAAE,WAAW,CAAC,OAAO,CAAC,GAAG,OAA2B,GAAG,OAAO;IAmBhF,KAAK,CAAC,YAAY,GAAE,WAAW,CAAC,OAAO,CAAC,GAAG,OAAyB,GAAG,IAAI;IAelE,OAAO,IAAI,IAAI;IAWxB,OAAO,CAAC,gBAAgB;IAOxB,OAAO,CAAC,eAAe;CAO1B"}
|
|
@@ -2,26 +2,42 @@ import { EventBubble } from '../debugging/eventBubble.js';
|
|
|
2
2
|
import type { QueryHandlerLike } from '../queryhandling/queryHandler.js';
|
|
3
3
|
import { BaseEmitter } from './baseEmitter.js';
|
|
4
4
|
import type { EmitterValue, ReadableEmitter } from './baseEmitter.js';
|
|
5
|
+
import type { RefreshableLiveResult } from './liveResult.js';
|
|
5
6
|
export type QueryArgumentEmitters = Record<string, ReadableEmitter<unknown, unknown>>;
|
|
6
7
|
export type QueryArgumentValues<TArguments extends QueryArgumentEmitters> = {
|
|
7
8
|
[TName in keyof TArguments]: EmitterValue<TArguments[TName]>;
|
|
8
9
|
};
|
|
10
|
+
export interface PollingScheduler {
|
|
11
|
+
schedule(callback: () => void, delayMs: number): unknown;
|
|
12
|
+
cancel(handle: unknown): void;
|
|
13
|
+
}
|
|
14
|
+
export interface LiveQueryPollingOptions {
|
|
15
|
+
intervalMs: number | ReadableEmitter<number, unknown>;
|
|
16
|
+
enabled?: boolean | ReadableEmitter<boolean, unknown>;
|
|
17
|
+
scheduler?: PollingScheduler;
|
|
18
|
+
}
|
|
9
19
|
export interface LiveQueryOptions<TResult, TArguments extends QueryArgumentEmitters> {
|
|
10
20
|
handler: QueryHandlerLike<QueryArgumentValues<TArguments>, TResult>;
|
|
11
21
|
args?: TArguments;
|
|
12
22
|
autoFetch?: boolean;
|
|
13
23
|
keepPreviousValue?: boolean;
|
|
24
|
+
polling?: LiveQueryPollingOptions;
|
|
14
25
|
owner?: unknown;
|
|
15
26
|
purpose?: string;
|
|
16
27
|
trace?: boolean;
|
|
17
28
|
}
|
|
18
29
|
/** Reactive, abortable query driven by a named record of emitter arguments. */
|
|
19
|
-
export declare class LiveQuery<TResult, TArguments extends QueryArgumentEmitters = Record<string, never>> extends BaseEmitter<TResult | undefined, unknown> {
|
|
30
|
+
export declare class LiveQuery<TResult, TArguments extends QueryArgumentEmitters = Record<string, never>> extends BaseEmitter<TResult | undefined, unknown> implements RefreshableLiveResult<TResult | undefined, unknown> {
|
|
20
31
|
readonly handler: QueryHandlerLike<QueryArgumentValues<TArguments>, TResult>;
|
|
21
32
|
readonly args: TArguments;
|
|
22
33
|
readonly keepPreviousValue: boolean;
|
|
23
34
|
private lastSuccessfulValue;
|
|
35
|
+
private hasSuccessfulValue;
|
|
24
36
|
private argumentUnsubscribers;
|
|
37
|
+
private pollingUnsubscribers;
|
|
38
|
+
private readonly polling;
|
|
39
|
+
private readonly pollingScheduler;
|
|
40
|
+
private pollingHandle;
|
|
25
41
|
private requestId;
|
|
26
42
|
private abortController;
|
|
27
43
|
/** Exposed for deterministic tests; consumers should use refresh()/retry(). */
|
|
@@ -30,7 +46,11 @@ export declare class LiveQuery<TResult, TArguments extends QueryArgumentEmitters
|
|
|
30
46
|
get argumentValues(): QueryArgumentValues<TArguments>;
|
|
31
47
|
refresh(eventOrCause?: EventBubble<unknown> | unknown): Promise<TResult | undefined>;
|
|
32
48
|
retry(eventOrCause?: EventBubble<unknown> | unknown): Promise<TResult | undefined>;
|
|
49
|
+
abort(eventOrCause?: EventBubble<unknown> | unknown): void;
|
|
33
50
|
dispose(): void;
|
|
51
|
+
private initializePolling;
|
|
52
|
+
private scheduleNextPoll;
|
|
53
|
+
private cancelScheduledPoll;
|
|
34
54
|
private isCurrentRequest;
|
|
35
55
|
}
|
|
36
56
|
//# sourceMappingURL=liveQuery.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"liveQuery.d.ts","sourceRoot":"","sources":["../../src/emitters/liveQuery.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,WAAW,EAAC,MAAM,6BAA6B,CAAA;AAEvD,OAAO,KAAK,EAAC,gBAAgB,EAAmC,MAAM,kCAAkC,CAAA;AACxG,OAAO,EAAC,WAAW,EAAC,MAAM,kBAAkB,CAAA;AAC5C,OAAO,KAAK,EAAC,YAAY,EAAE,eAAe,EAAC,MAAM,kBAAkB,CAAA;
|
|
1
|
+
{"version":3,"file":"liveQuery.d.ts","sourceRoot":"","sources":["../../src/emitters/liveQuery.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { EventBubble } from '../debugging/eventBubble.js';
|
|
2
|
+
import type { ReadableEmitter } from './baseEmitter.js';
|
|
3
|
+
/** Common caller-facing contract for remote and locally derived live results. */
|
|
4
|
+
export interface LiveResult<TValue, TError = unknown> extends ReadableEmitter<TValue, TError> {
|
|
5
|
+
readonly disposed: boolean;
|
|
6
|
+
dispose(): void;
|
|
7
|
+
}
|
|
8
|
+
/** Capabilities available only when a result can re-execute its source. */
|
|
9
|
+
export interface RefreshableLiveResult<TValue, TError = unknown> extends LiveResult<TValue, TError> {
|
|
10
|
+
refresh(eventOrCause?: EventBubble<unknown> | unknown): Promise<TValue>;
|
|
11
|
+
retry(eventOrCause?: EventBubble<unknown> | unknown): Promise<TValue>;
|
|
12
|
+
abort(eventOrCause?: EventBubble<unknown> | unknown): void;
|
|
13
|
+
}
|
|
14
|
+
//# sourceMappingURL=liveResult.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"liveResult.d.ts","sourceRoot":"","sources":["../../src/emitters/liveResult.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,WAAW,EAAC,MAAM,6BAA6B,CAAA;AAC5D,OAAO,KAAK,EAAC,eAAe,EAAC,MAAM,kBAAkB,CAAA;AAErD,iFAAiF;AACjF,MAAM,WAAW,UAAU,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAChD,SAAQ,eAAe,CAAC,MAAM,EAAE,MAAM,CAAC;IACvC,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAA;IAC1B,OAAO,IAAI,IAAI,CAAA;CAClB;AAED,2EAA2E;AAC3E,MAAM,WAAW,qBAAqB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAC3D,SAAQ,UAAU,CAAC,MAAM,EAAE,MAAM,CAAC;IAClC,OAAO,CAAC,YAAY,CAAC,EAAE,WAAW,CAAC,OAAO,CAAC,GAAG,OAAO,GAAG,OAAO,CAAC,MAAM,CAAC,CAAA;IACvE,KAAK,CAAC,YAAY,CAAC,EAAE,WAAW,CAAC,OAAO,CAAC,GAAG,OAAO,GAAG,OAAO,CAAC,MAAM,CAAC,CAAA;IACrE,KAAK,CAAC,YAAY,CAAC,EAAE,WAAW,CAAC,OAAO,CAAC,GAAG,OAAO,GAAG,IAAI,CAAA;CAC7D"}
|
package/dist/index.d.ts
CHANGED
|
@@ -5,13 +5,18 @@ export type { BubbleGraph, EventListener } from './debugging/eventBus.js';
|
|
|
5
5
|
export { BaseEmitter, DerivedEmitter } from './emitters/baseEmitter.js';
|
|
6
6
|
export type { DerivedEmitterOptions, DerivedErrorEntry, DerivedErrors, EmitterNotification, EmitterOptions, EmitterValue, EmitterValues, MapOptions, ReadableEmitter, SnapshotUpdate, SubscribeOptions, } from './emitters/baseEmitter.js';
|
|
7
7
|
export { Emitter } from './emitters/emitter.js';
|
|
8
|
+
export { AsyncCommand, AsyncCommandConcurrencyError } from './commands/asyncCommand.js';
|
|
9
|
+
export type { AsyncCommandConcurrency, AsyncCommandContext, AsyncCommandExecutor, AsyncCommandOptions, } from './commands/asyncCommand.js';
|
|
8
10
|
export { LiveQuery } from './emitters/liveQuery.js';
|
|
9
|
-
export type { LiveQueryOptions, QueryArgumentEmitters, QueryArgumentValues, } from './emitters/liveQuery.js';
|
|
11
|
+
export type { LiveQueryPollingOptions, LiveQueryOptions, PollingScheduler, QueryArgumentEmitters, QueryArgumentValues, } from './emitters/liveQuery.js';
|
|
12
|
+
export type { LiveResult, RefreshableLiveResult } from './emitters/liveResult.js';
|
|
10
13
|
export { combineFetchStates, FetchState, FetchStateValues } from './enums/fetchState.js';
|
|
11
14
|
export type { FetchStateValue } from './enums/fetchState.js';
|
|
12
15
|
export { QueryArg } from './queryhandling/queryArg.js';
|
|
13
16
|
export { QueryHandler } from './queryhandling/queryHandler.js';
|
|
14
17
|
export type { AbortSignalLike, QueryHandlerLike, QueryRequestOptions, QueryValues, } from './queryhandling/queryHandler.js';
|
|
15
18
|
export { RestQueryHandler } from './queryhandling/restQueryHandler.js';
|
|
16
|
-
export type { FetchLike, JsonResponseLike, QuerySerializer, RestQueryHandlerOptions, SearchParamsLike, UrlLike, } from './queryhandling/restQueryHandler.js';
|
|
19
|
+
export type { FetchLike, JsonResponseLike, QuerySerializer, ResultParser, RestQueryHandlerOptions, SearchParamsLike, UrlLike, } from './queryhandling/restQueryHandler.js';
|
|
20
|
+
export { DerivedEndpoint, DerivedLiveResult, derivedEndpoint, QueryEndpoint, queryEndpoint, RestEndpoint, restEndpoint, } from './queryhandling/endpoints.js';
|
|
21
|
+
export type { DerivedEndpointOptions, EndpointArgumentEmitters, EndpointQueryOptions, OpenDerivedEndpointOptions, QueryEndpointOptions, RestEndpointOptions, } from './queryhandling/endpoints.js';
|
|
17
22
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,WAAW,EAAC,MAAM,4BAA4B,CAAA;AACtD,YAAY,EAAC,YAAY,EAAC,MAAM,4BAA4B,CAAA;AAC5D,OAAO,EAAC,QAAQ,EAAC,MAAM,yBAAyB,CAAA;AAChD,YAAY,EAAC,WAAW,EAAE,aAAa,EAAC,MAAM,yBAAyB,CAAA;AAEvE,OAAO,EAAC,WAAW,EAAE,cAAc,EAAC,MAAM,2BAA2B,CAAA;AACrE,YAAY,EACR,qBAAqB,EACrB,iBAAiB,EACjB,aAAa,EACb,mBAAmB,EACnB,cAAc,EACd,YAAY,EACZ,aAAa,EACb,UAAU,EACV,eAAe,EACf,cAAc,EACd,gBAAgB,GACnB,MAAM,2BAA2B,CAAA;AAClC,OAAO,EAAC,OAAO,EAAC,MAAM,uBAAuB,CAAA;AAC7C,OAAO,EAAC,SAAS,EAAC,MAAM,yBAAyB,CAAA;AACjD,YAAY,EACR,gBAAgB,EAChB,qBAAqB,EACrB,mBAAmB,GACtB,MAAM,yBAAyB,CAAA;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,WAAW,EAAC,MAAM,4BAA4B,CAAA;AACtD,YAAY,EAAC,YAAY,EAAC,MAAM,4BAA4B,CAAA;AAC5D,OAAO,EAAC,QAAQ,EAAC,MAAM,yBAAyB,CAAA;AAChD,YAAY,EAAC,WAAW,EAAE,aAAa,EAAC,MAAM,yBAAyB,CAAA;AAEvE,OAAO,EAAC,WAAW,EAAE,cAAc,EAAC,MAAM,2BAA2B,CAAA;AACrE,YAAY,EACR,qBAAqB,EACrB,iBAAiB,EACjB,aAAa,EACb,mBAAmB,EACnB,cAAc,EACd,YAAY,EACZ,aAAa,EACb,UAAU,EACV,eAAe,EACf,cAAc,EACd,gBAAgB,GACnB,MAAM,2BAA2B,CAAA;AAClC,OAAO,EAAC,OAAO,EAAC,MAAM,uBAAuB,CAAA;AAC7C,OAAO,EAAC,YAAY,EAAE,4BAA4B,EAAC,MAAM,4BAA4B,CAAA;AACrF,YAAY,EACR,uBAAuB,EACvB,mBAAmB,EACnB,oBAAoB,EACpB,mBAAmB,GACtB,MAAM,4BAA4B,CAAA;AACnC,OAAO,EAAC,SAAS,EAAC,MAAM,yBAAyB,CAAA;AACjD,YAAY,EACR,uBAAuB,EACvB,gBAAgB,EAChB,gBAAgB,EAChB,qBAAqB,EACrB,mBAAmB,GACtB,MAAM,yBAAyB,CAAA;AAChC,YAAY,EAAC,UAAU,EAAE,qBAAqB,EAAC,MAAM,0BAA0B,CAAA;AAE/E,OAAO,EAAC,kBAAkB,EAAE,UAAU,EAAE,gBAAgB,EAAC,MAAM,uBAAuB,CAAA;AACtF,YAAY,EAAC,eAAe,EAAC,MAAM,uBAAuB,CAAA;AAE1D,OAAO,EAAC,QAAQ,EAAC,MAAM,6BAA6B,CAAA;AACpD,OAAO,EAAC,YAAY,EAAC,MAAM,iCAAiC,CAAA;AAC5D,YAAY,EACR,eAAe,EACf,gBAAgB,EAChB,mBAAmB,EACnB,WAAW,GACd,MAAM,iCAAiC,CAAA;AACxC,OAAO,EAAC,gBAAgB,EAAC,MAAM,qCAAqC,CAAA;AACpE,YAAY,EACR,SAAS,EACT,gBAAgB,EAChB,eAAe,EACf,YAAY,EACZ,uBAAuB,EACvB,gBAAgB,EAChB,OAAO,GACV,MAAM,qCAAqC,CAAA;AAC5C,OAAO,EACH,eAAe,EACf,iBAAiB,EACjB,eAAe,EACf,aAAa,EACb,aAAa,EACb,YAAY,EACZ,YAAY,GACf,MAAM,8BAA8B,CAAA;AACrC,YAAY,EACR,sBAAsB,EACtB,wBAAwB,EACxB,oBAAoB,EACpB,0BAA0B,EAC1B,oBAAoB,EACpB,mBAAmB,GACtB,MAAM,8BAA8B,CAAA"}
|