@lde/search 0.32.3 → 0.33.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/dist/adapter.d.ts CHANGED
@@ -15,4 +15,5 @@ export { joinGraph, MAX_JOIN_DEPTH } from './join-graph.js';
15
15
  export type { JoinGraph } from './join-graph.js';
16
16
  export { filterOperatorFor, filterOperator, filterOn, isWelded, isUnsatisfiable, facetSearches, validateQuery, assertValidQuery, resolvePath, pageForOffset, } from './query.js';
17
17
  export type { FacetSearch, FilterOperator, QueryIssue, ResolvedPath, PathFailure, } from './query.js';
18
+ export type { RebuildRequests } from './rebuild.js';
18
19
  //# sourceMappingURL=adapter.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"adapter.d.ts","sourceRoot":"","sources":["../src/adapter.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,EACL,kBAAkB,EAClB,cAAc,EACd,OAAO,EACP,gBAAgB,EAChB,mBAAmB,EACnB,aAAa,EACb,gBAAgB,EAChB,eAAe,EACf,gBAAgB,EAChB,cAAc,EACd,YAAY,EACZ,eAAe,EACf,iBAAiB,EACjB,mBAAmB,EACnB,eAAe,EACf,oBAAoB,EACpB,mBAAmB,EACnB,cAAc,EACd,YAAY,EACZ,eAAe,EACf,iBAAiB,EACjB,sBAAsB,EACtB,eAAe,EACf,kBAAkB,EAClB,aAAa,EACb,kBAAkB,EAClB,UAAU,EACV,YAAY,EACZ,QAAQ,EACR,OAAO,EACP,MAAM,EACN,YAAY,EACZ,gBAAgB,EAChB,kBAAkB,EAClB,kBAAkB,EAClB,aAAa,EACb,mBAAmB,EACnB,YAAY,EACZ,kBAAkB,EAClB,aAAa,EACb,gBAAgB,EAChB,gBAAgB,GACjB,MAAM,aAAa,CAAC;AACrB,YAAY,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAClD,OAAO,EAAE,qBAAqB,EAAE,MAAM,cAAc,CAAC;AACrD,OAAO,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AACxD,OAAO,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAC9C,OAAO,EAAE,SAAS,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAC5D,YAAY,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AACjD,OAAO,EACL,iBAAiB,EACjB,cAAc,EACd,QAAQ,EACR,QAAQ,EACR,eAAe,EACf,aAAa,EACb,aAAa,EACb,gBAAgB,EAChB,WAAW,EACX,aAAa,GACd,MAAM,YAAY,CAAC;AACpB,YAAY,EACV,WAAW,EACX,cAAc,EACd,UAAU,EACV,YAAY,EACZ,WAAW,GACZ,MAAM,YAAY,CAAC"}
1
+ {"version":3,"file":"adapter.d.ts","sourceRoot":"","sources":["../src/adapter.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,EACL,kBAAkB,EAClB,cAAc,EACd,OAAO,EACP,gBAAgB,EAChB,mBAAmB,EACnB,aAAa,EACb,gBAAgB,EAChB,eAAe,EACf,gBAAgB,EAChB,cAAc,EACd,YAAY,EACZ,eAAe,EACf,iBAAiB,EACjB,mBAAmB,EACnB,eAAe,EACf,oBAAoB,EACpB,mBAAmB,EACnB,cAAc,EACd,YAAY,EACZ,eAAe,EACf,iBAAiB,EACjB,sBAAsB,EACtB,eAAe,EACf,kBAAkB,EAClB,aAAa,EACb,kBAAkB,EAClB,UAAU,EACV,YAAY,EACZ,QAAQ,EACR,OAAO,EACP,MAAM,EACN,YAAY,EACZ,gBAAgB,EAChB,kBAAkB,EAClB,kBAAkB,EAClB,aAAa,EACb,mBAAmB,EACnB,YAAY,EACZ,kBAAkB,EAClB,aAAa,EACb,gBAAgB,EAChB,gBAAgB,GACjB,MAAM,aAAa,CAAC;AACrB,YAAY,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAClD,OAAO,EAAE,qBAAqB,EAAE,MAAM,cAAc,CAAC;AACrD,OAAO,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AACxD,OAAO,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAC9C,OAAO,EAAE,SAAS,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAC5D,YAAY,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AACjD,OAAO,EACL,iBAAiB,EACjB,cAAc,EACd,QAAQ,EACR,QAAQ,EACR,eAAe,EACf,aAAa,EACb,aAAa,EACb,gBAAgB,EAChB,WAAW,EACX,aAAa,GACd,MAAM,YAAY,CAAC;AACpB,YAAY,EACV,WAAW,EACX,cAAc,EACd,UAAU,EACV,YAAY,EACZ,WAAW,GACZ,MAAM,YAAY,CAAC;AACpB,YAAY,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC"}
package/dist/index.d.ts CHANGED
@@ -9,4 +9,5 @@ export type { SearchQuery, ReferenceProjection, Filter, Criterion, CriterionBase
9
9
  export { NESTED_DOCUMENT_TYPE } from './engine.js';
10
10
  export type { SearchEngine, SearchResult, SearchHit, ResultDocument, SearchValue, LocalizedValue, Reference, NestedDocument, Facet, FacetBucket, FacetExtent, FacetMap, FacetsOutcome, FacetFieldsOf, OutputFieldsOf, } from './engine.js';
11
11
  export type { FramedNode } from './frame-by-type.js';
12
+ export { RebuildAlreadyRunning, requestRebuild } from './rebuild.js';
12
13
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AASA,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAC5C,YAAY,EACV,aAAa,EACb,iBAAiB,EACjB,cAAc,GACf,MAAM,cAAc,CAAC;AAKtB,OAAO,EACL,gBAAgB,EAChB,YAAY,EACZ,kBAAkB,EAClB,qBAAqB,EACrB,QAAQ,EACR,OAAO,EACP,MAAM,EAMN,gBAAgB,EAChB,gBAAgB,GACjB,MAAM,aAAa,CAAC;AACrB,YAAY,EACV,SAAS,EACT,WAAW,EACX,eAAe,EACf,SAAS,EACT,YAAY,EACZ,cAAc,EACd,iBAAiB,EACjB,YAAY,EACZ,YAAY,EACZ,UAAU,EACV,cAAc,EACd,QAAQ,EACR,aAAa,EACb,UAAU,EACV,eAAe,EACf,QAAQ,EACR,SAAS,EACT,YAAY,EACZ,UAAU,EACV,eAAe,GAChB,MAAM,aAAa,CAAC;AAKrB,OAAO,EAAE,SAAS,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAC5D,YAAY,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAOjD,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AACtC,YAAY,EACV,WAAW,EACX,mBAAmB,EACnB,MAAM,EACN,SAAS,EACT,aAAa,EACb,eAAe,EACf,IAAI,GACL,MAAM,YAAY,CAAC;AAIpB,OAAO,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AACnD,YAAY,EACV,YAAY,EACZ,YAAY,EACZ,SAAS,EACT,cAAc,EACd,WAAW,EACX,cAAc,EACd,SAAS,EACT,cAAc,EACd,KAAK,EACL,WAAW,EACX,WAAW,EACX,QAAQ,EACR,aAAa,EACb,aAAa,EACb,cAAc,GACf,MAAM,aAAa,CAAC;AAErB,YAAY,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AASA,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAC5C,YAAY,EACV,aAAa,EACb,iBAAiB,EACjB,cAAc,GACf,MAAM,cAAc,CAAC;AAKtB,OAAO,EACL,gBAAgB,EAChB,YAAY,EACZ,kBAAkB,EAClB,qBAAqB,EACrB,QAAQ,EACR,OAAO,EACP,MAAM,EAMN,gBAAgB,EAChB,gBAAgB,GACjB,MAAM,aAAa,CAAC;AACrB,YAAY,EACV,SAAS,EACT,WAAW,EACX,eAAe,EACf,SAAS,EACT,YAAY,EACZ,cAAc,EACd,iBAAiB,EACjB,YAAY,EACZ,YAAY,EACZ,UAAU,EACV,cAAc,EACd,QAAQ,EACR,aAAa,EACb,UAAU,EACV,eAAe,EACf,QAAQ,EACR,SAAS,EACT,YAAY,EACZ,UAAU,EACV,eAAe,GAChB,MAAM,aAAa,CAAC;AAKrB,OAAO,EAAE,SAAS,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAC5D,YAAY,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAOjD,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AACtC,YAAY,EACV,WAAW,EACX,mBAAmB,EACnB,MAAM,EACN,SAAS,EACT,aAAa,EACb,eAAe,EACf,IAAI,GACL,MAAM,YAAY,CAAC;AAIpB,OAAO,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AACnD,YAAY,EACV,YAAY,EACZ,YAAY,EACZ,SAAS,EACT,cAAc,EACd,WAAW,EACX,cAAc,EACd,SAAS,EACT,cAAc,EACd,KAAK,EACL,WAAW,EACX,WAAW,EACX,QAAQ,EACR,aAAa,EACb,aAAa,EACb,cAAc,GACf,MAAM,aAAa,CAAC;AAErB,YAAY,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAKrD,OAAO,EAAE,qBAAqB,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC"}
package/dist/index.js CHANGED
@@ -30,3 +30,7 @@ export { filterOn } from './query.js';
30
30
  // Engine port + the logical result document returned across it. An engine is
31
31
  // bound to the whole SearchSchema at construction by its adapter factory.
32
32
  export { NESTED_DOCUMENT_TYPE } from './engine.js';
33
+ // Rebuild requests: hand a request to the run holding an index’s rebuild lock
34
+ // instead of dropping it. The store a port records requests in
35
+ // (`RebuildRequests`) is on the adapter surface.
36
+ export { RebuildAlreadyRunning, requestRebuild } from './rebuild.js';
@@ -0,0 +1,51 @@
1
+ /**
2
+ * Another run already holds the index’s rebuild lock, so this run refuses to
3
+ * open. Rebuilds are single-flight per index across pods: an engine port’s
4
+ * rebuild writer throws this from `openRun` when its lock is held.
5
+ * {@link requestRebuild} catches it to hand the request to the run holding the
6
+ * lock; a caller driving a writer directly can catch it to treat a concurrent
7
+ * rebuild as a graceful skip.
8
+ */
9
+ export declare class RebuildAlreadyRunning extends Error {
10
+ constructor(name: string);
11
+ }
12
+ /**
13
+ * Where an index’s rebuild requests are recorded, next to its rebuild lock, so
14
+ * the run holding the lock sees that a request arrived while it ran. An engine
15
+ * port implements it on its own store; {@link requestRebuild} is its only
16
+ * caller.
17
+ */
18
+ export interface RebuildRequests {
19
+ /** Record a new request, replacing the previous one. */
20
+ record(): Promise<void>;
21
+ /**
22
+ * The latest request, or `undefined` when none was ever recorded. Opaque:
23
+ * only compared for equality, to tell whether a request arrived since the
24
+ * last read.
25
+ */
26
+ latest(): Promise<string | undefined>;
27
+ }
28
+ /**
29
+ * Request a rebuild of one index, so that a change made before the call ends
30
+ * up in it – even when another pod is rebuilding the index right now.
31
+ *
32
+ * The request is recorded first, then `rebuild` runs. When another run holds
33
+ * the lock (`rebuild` throws {@link RebuildAlreadyRunning}), this call resolves
34
+ * at once: the holder reads the requests after its run and runs again,
35
+ * picking the change up. A run that finds a request recorded since it began
36
+ * runs again too, so a burst of requests during one run costs a single rerun.
37
+ * Requests that keep arriving keep the holder running until one run sees none.
38
+ *
39
+ * The ordering is what makes it safe: a requester records before it tries the
40
+ * lock, and the holder reads after its run released the lock. So either the
41
+ * requester takes the lock, or the holder sees its request.
42
+ *
43
+ * Every rebuild of the index must go through `requestRebuild` with the same
44
+ * `rebuild`: the holder runs its own on another’s behalf, and a run started
45
+ * any other way never reads the requests. `requests` must be named after the
46
+ * one lock `rebuild` can be refused by. On failure this rejects without
47
+ * running again; requests recorded during the failed run are served by the
48
+ * next `requestRebuild`.
49
+ */
50
+ export declare function requestRebuild(rebuild: () => Promise<unknown>, requests: RebuildRequests): Promise<void>;
51
+ //# sourceMappingURL=rebuild.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rebuild.d.ts","sourceRoot":"","sources":["../src/rebuild.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,qBAAa,qBAAsB,SAAQ,KAAK;gBAClC,IAAI,EAAE,MAAM;CAIzB;AAED;;;;;GAKG;AACH,MAAM,WAAW,eAAe;IAC9B,wDAAwD;IACxD,MAAM,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IACxB;;;;OAIG;IACH,MAAM,IAAI,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAAC;CACvC;AAED;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAsB,cAAc,CAClC,OAAO,EAAE,MAAM,OAAO,CAAC,OAAO,CAAC,EAC/B,QAAQ,EAAE,eAAe,GACxB,OAAO,CAAC,IAAI,CAAC,CAsBf"}
@@ -0,0 +1,60 @@
1
+ /**
2
+ * Another run already holds the index’s rebuild lock, so this run refuses to
3
+ * open. Rebuilds are single-flight per index across pods: an engine port’s
4
+ * rebuild writer throws this from `openRun` when its lock is held.
5
+ * {@link requestRebuild} catches it to hand the request to the run holding the
6
+ * lock; a caller driving a writer directly can catch it to treat a concurrent
7
+ * rebuild as a graceful skip.
8
+ */
9
+ export class RebuildAlreadyRunning extends Error {
10
+ constructor(name) {
11
+ super(`Another rebuild of “${name}” is already running`);
12
+ this.name = 'RebuildAlreadyRunning';
13
+ }
14
+ }
15
+ /**
16
+ * Request a rebuild of one index, so that a change made before the call ends
17
+ * up in it – even when another pod is rebuilding the index right now.
18
+ *
19
+ * The request is recorded first, then `rebuild` runs. When another run holds
20
+ * the lock (`rebuild` throws {@link RebuildAlreadyRunning}), this call resolves
21
+ * at once: the holder reads the requests after its run and runs again,
22
+ * picking the change up. A run that finds a request recorded since it began
23
+ * runs again too, so a burst of requests during one run costs a single rerun.
24
+ * Requests that keep arriving keep the holder running until one run sees none.
25
+ *
26
+ * The ordering is what makes it safe: a requester records before it tries the
27
+ * lock, and the holder reads after its run released the lock. So either the
28
+ * requester takes the lock, or the holder sees its request.
29
+ *
30
+ * Every rebuild of the index must go through `requestRebuild` with the same
31
+ * `rebuild`: the holder runs its own on another’s behalf, and a run started
32
+ * any other way never reads the requests. `requests` must be named after the
33
+ * one lock `rebuild` can be refused by. On failure this rejects without
34
+ * running again; requests recorded during the failed run are served by the
35
+ * next `requestRebuild`.
36
+ */
37
+ export async function requestRebuild(rebuild, requests) {
38
+ await requests.record();
39
+ // Read before the run reads its source, so a request recorded after this
40
+ // point shows up as a change once the run is done.
41
+ let served = await requests.latest();
42
+ for (;;) {
43
+ try {
44
+ await rebuild();
45
+ }
46
+ catch (error) {
47
+ // By name, not `instanceof`: the port may resolve its own copy of this
48
+ // package, whose class is a different one.
49
+ if (error instanceof Error && error.name === 'RebuildAlreadyRunning') {
50
+ return;
51
+ }
52
+ throw error;
53
+ }
54
+ const latest = await requests.latest();
55
+ if (latest === served) {
56
+ return;
57
+ }
58
+ served = latest;
59
+ }
60
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lde/search",
3
- "version": "0.32.3",
3
+ "version": "0.33.0",
4
4
  "description": "Engine- and domain-agnostic core for RDF-backed search: a unified declarative field model (SearchField/SearchType/SearchSchema), a neutral query IR, the SearchEngine port with logical result types, and a streaming CONSTRUCT-to-document projection. Bakes in no engine, protocol, or domain.",
5
5
  "repository": {
6
6
  "url": "git+https://github.com/ldelements/lde.git",