@hviana/sema 0.7.8 → 0.7.9

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.
@@ -898,8 +898,16 @@ export class GraphSearch {
898
898
  for (const site of this.host.recogniseSpan(fact.bytes).sites) {
899
899
  if (site.payload < 0 || site.payload === fact.node)
900
900
  continue;
901
- if (!this.store.hasNext(site.payload) &&
902
- !this.store.hasHalo(site.payload))
901
+ // The admission predicate has ONE definition — `traverse.ts`'s
902
+ // `leadsSomewhere` (edge or halo). The host LENDS it when it can (Mind
903
+ // does, with the response-scoped struct cache); a bare host falls back to
904
+ // the raw-store probe, so the search stays host-based. Same semantics
905
+ // either way; the hook spares the repeated probe and keeps the predicate
906
+ // from being redefined here.
907
+ const leads = this.host.leadsSomewhere !== undefined
908
+ ? this.host.leadsSomewhere(site.payload)
909
+ : this.store.hasNext(site.payload) || this.store.hasHalo(site.payload);
910
+ if (!leads)
903
911
  continue;
904
912
  const key = this.host.resolve(concat2(this.store.bytesPrefix(site.payload, ALL), tail));
905
913
  if (key === null)
@@ -150,6 +150,11 @@ export declare class Mind implements MindContext {
150
150
  private _conversations;
151
151
  /** Canonical node id of a byte span. Required by GraphSearchHost & MindContext. */
152
152
  resolve(bytes: Uint8Array): number | null;
153
+ /** Whether a node leads somewhere — the admission predicate, delegating to
154
+ * `traverse.ts`'s ONE definition (edge or halo, with its response-scoped
155
+ * cache). The search holds a bare Store and cannot reach that cache itself,
156
+ * so it asks through this hook; a bare host keeps its raw-store fallback. */
157
+ leadsSomewhere(id: number): boolean;
153
158
  recogniseSpan(bytes: Uint8Array): {
154
159
  sites: ReadonlyArray<Site>;
155
160
  leaves: ReadonlyArray<Leaf>;
@@ -20,7 +20,7 @@ import { GraphSearch, } from "./graph-search.js";
20
20
  import { Alu } from "../alu/src/index.js";
21
21
  import { decodeText, Rationale, } from "./rationale.js";
22
22
  import { gistOf, inputBytes, perceive as perceiveImpl, perceiveKey, resolve as resolveImpl, } from "./primitives.js";
23
- import { chooseNext, edgeAncestors as edgeAncestorsFn, invalidateStructuralCaches, } from "./traverse.js";
23
+ import { chooseNext, edgeAncestors as edgeAncestorsFn, invalidateStructuralCaches, leadsSomewhere, } from "./traverse.js";
24
24
  import { invalidateJunctionCache } from "./junction.js";
25
25
  import { follow } from "./match.js";
26
26
  import { recognise, segment } from "./recognition.js";
@@ -112,6 +112,13 @@ export class Mind {
112
112
  resolve(bytes) {
113
113
  return resolveImpl(this, bytes);
114
114
  }
115
+ /** Whether a node leads somewhere — the admission predicate, delegating to
116
+ * `traverse.ts`'s ONE definition (edge or halo, with its response-scoped
117
+ * cache). The search holds a bare Store and cannot reach that cache itself,
118
+ * so it asks through this hook; a bare host keeps its raw-store fallback. */
119
+ leadsSomewhere(id) {
120
+ return leadsSomewhere(this, id);
121
+ }
115
122
  // recogniseSpan wraps recognise
116
123
  recogniseSpan(bytes) {
117
124
  const r = recognise(this, bytes);
@@ -35,6 +35,12 @@ export interface GraphSearchHost {
35
35
  starts: ReadonlySet<number>;
36
36
  };
37
37
  chooseNext?(node: number): number | undefined;
38
+ /** The admission predicate — `traverse.ts`'s `leadsSomewhere`, its ONE
39
+ * definition: does this node bear an edge or a halo? Optional, so a bare
40
+ * host (a raw Store and nothing else) still works; when present, the search
41
+ * uses it rather than re-probing the store, which keeps the predicate
42
+ * single-defined AND memoised on the response-scoped struct cache. */
43
+ leadsSomewhere?(id: number): boolean;
38
44
  }
39
45
  export interface Recognition {
40
46
  /** Forms that can lead somewhere — they have an edge or a halo. */
package/jsr.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "$schema": "https://jsr.io/schema/config-file.v1.json",
3
3
  "name": "@hviana/sema",
4
- "version": "0.7.8",
4
+ "version": "0.7.9",
5
5
  "exports": "./src/index.ts"
6
6
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hviana/sema",
3
- "version": "0.7.8",
3
+ "version": "0.7.9",
4
4
  "description": "Sema: a non-parametric, instance-based reasoning system.",
5
5
  "repository": {
6
6
  "type": "git",
@@ -1168,10 +1168,16 @@ export class GraphSearch {
1168
1168
  // itself, not an entity inside it.
1169
1169
  for (const site of this.host.recogniseSpan(fact.bytes).sites) {
1170
1170
  if (site.payload < 0 || site.payload === fact.node) continue;
1171
- if (
1172
- !this.store.hasNext(site.payload) &&
1173
- !this.store.hasHalo(site.payload)
1174
- ) continue;
1171
+ // The admission predicate has ONE definition — `traverse.ts`'s
1172
+ // `leadsSomewhere` (edge or halo). The host LENDS it when it can (Mind
1173
+ // does, with the response-scoped struct cache); a bare host falls back to
1174
+ // the raw-store probe, so the search stays host-based. Same semantics
1175
+ // either way; the hook spares the repeated probe and keeps the predicate
1176
+ // from being redefined here.
1177
+ const leads = this.host.leadsSomewhere !== undefined
1178
+ ? this.host.leadsSomewhere(site.payload)
1179
+ : this.store.hasNext(site.payload) || this.store.hasHalo(site.payload);
1180
+ if (!leads) continue;
1175
1181
  const key = this.host.resolve(
1176
1182
  concat2(this.store.bytesPrefix(site.payload, ALL), tail),
1177
1183
  );
package/src/mind/mind.ts CHANGED
@@ -159,6 +159,7 @@ import {
159
159
  chooseNext,
160
160
  edgeAncestors as edgeAncestorsFn,
161
161
  invalidateStructuralCaches,
162
+ leadsSomewhere,
162
163
  } from "./traverse.js";
163
164
  import { invalidateJunctionCache } from "./junction.js";
164
165
  import { follow } from "./match.js";
@@ -343,6 +344,14 @@ export class Mind implements MindContext {
343
344
  return resolveImpl(this, bytes);
344
345
  }
345
346
 
347
+ /** Whether a node leads somewhere — the admission predicate, delegating to
348
+ * `traverse.ts`'s ONE definition (edge or halo, with its response-scoped
349
+ * cache). The search holds a bare Store and cannot reach that cache itself,
350
+ * so it asks through this hook; a bare host keeps its raw-store fallback. */
351
+ leadsSomewhere(id: number): boolean {
352
+ return leadsSomewhere(this, id);
353
+ }
354
+
346
355
  // recogniseSpan wraps recognise
347
356
  recogniseSpan(bytes: Uint8Array): {
348
357
  sites: ReadonlyArray<Site>;
package/src/mind/types.ts CHANGED
@@ -65,6 +65,12 @@ export interface GraphSearchHost {
65
65
  starts: ReadonlySet<number>;
66
66
  };
67
67
  chooseNext?(node: number): number | undefined;
68
+ /** The admission predicate — `traverse.ts`'s `leadsSomewhere`, its ONE
69
+ * definition: does this node bear an edge or a halo? Optional, so a bare
70
+ * host (a raw Store and nothing else) still works; when present, the search
71
+ * uses it rather than re-probing the store, which keeps the predicate
72
+ * single-defined AND memoised on the response-scoped struct cache. */
73
+ leadsSomewhere?(id: number): boolean;
68
74
  }
69
75
 
70
76
  // ═══════════════════════════════════════════════════════════════════════════