@rolexjs/core 1.5.0-dev-20260309145703 → 1.5.0-dev-20260310014736
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/index.d.ts +28 -3
- package/dist/index.js +46 -41
- package/dist/index.js.map +1 -1
- package/package.json +3 -3
package/dist/index.d.ts
CHANGED
|
@@ -167,6 +167,31 @@ declare const dissolve: _rolexjs_system.Process;
|
|
|
167
167
|
declare const abolish: _rolexjs_system.Process;
|
|
168
168
|
declare const rehire: _rolexjs_system.Process;
|
|
169
169
|
|
|
170
|
+
/**
|
|
171
|
+
* Projection — the single projection pipeline for RoleX.
|
|
172
|
+
*
|
|
173
|
+
* Pipeline: raw project → compact(depth) → enrich permissions.
|
|
174
|
+
*
|
|
175
|
+
* All projections go through this pipeline. No special cases.
|
|
176
|
+
* Control behavior via ProjectionContext.
|
|
177
|
+
*
|
|
178
|
+
* Rules:
|
|
179
|
+
* - Root (depth 0): full
|
|
180
|
+
* - Level 1 children: full (with content)
|
|
181
|
+
* - Level 2+ grandchildren: compact (name/id/tag only, no subtree)
|
|
182
|
+
* - Reverse links: compact immediately
|
|
183
|
+
* - Forward links: keep children but strip nested links
|
|
184
|
+
*/
|
|
185
|
+
|
|
186
|
+
interface ProjectionContext {
|
|
187
|
+
/** Children expansion depth. Default 1: one level fully expanded, then compact. */
|
|
188
|
+
depth?: number;
|
|
189
|
+
}
|
|
190
|
+
interface Projection {
|
|
191
|
+
/** Project a node through the full pipeline: raw → compact → enrich. */
|
|
192
|
+
(node: Structure, ctx?: ProjectionContext): Promise<State>;
|
|
193
|
+
}
|
|
194
|
+
|
|
170
195
|
/**
|
|
171
196
|
* Commands — platform-agnostic command implementations.
|
|
172
197
|
*
|
|
@@ -188,6 +213,7 @@ interface CommandContext {
|
|
|
188
213
|
past: Structure;
|
|
189
214
|
resolve(id: string): Structure | Promise<Structure>;
|
|
190
215
|
find(id: string): (Structure | null) | Promise<Structure | null>;
|
|
216
|
+
project: Projection;
|
|
191
217
|
resourcex?: ResourceX;
|
|
192
218
|
issuex?: IssueX;
|
|
193
219
|
prototype?: PrototypeRepository;
|
|
@@ -414,6 +440,7 @@ interface RoleX {
|
|
|
414
440
|
declare class RoleXService implements RoleX {
|
|
415
441
|
private rt;
|
|
416
442
|
private commands;
|
|
443
|
+
private project;
|
|
417
444
|
private resourcex?;
|
|
418
445
|
private issuex?;
|
|
419
446
|
private repo;
|
|
@@ -438,10 +465,8 @@ declare class RoleXService implements RoleX {
|
|
|
438
465
|
direct<T = unknown>(locator: string, args?: Record<string, unknown>, options?: {
|
|
439
466
|
raw?: boolean;
|
|
440
467
|
}): Promise<T>;
|
|
441
|
-
/** Find a node by id across the entire society tree. */
|
|
468
|
+
/** Find a node by id across the entire society tree (raw, no pipeline). */
|
|
442
469
|
private find;
|
|
443
|
-
/** Find and project a node's full subtree by id. */
|
|
444
|
-
private projectById;
|
|
445
470
|
}
|
|
446
471
|
|
|
447
472
|
/**
|
package/dist/index.js
CHANGED
|
@@ -654,9 +654,9 @@ async function applyPrototype(data, repo, direct) {
|
|
|
654
654
|
import { parse } from "@rolexjs/parser";
|
|
655
655
|
import { structure as structure2 } from "@rolexjs/system";
|
|
656
656
|
function createCommands(ctx) {
|
|
657
|
-
const { rt, society: society2, past: past2, resolve, resourcex, issuex } = ctx;
|
|
657
|
+
const { rt, society: society2, past: past2, resolve, project: project2, resourcex, issuex } = ctx;
|
|
658
658
|
async function ok(node, process8) {
|
|
659
|
-
return { state: await
|
|
659
|
+
return { state: await project2(node), process: process8 };
|
|
660
660
|
}
|
|
661
661
|
async function archive2(node, process8) {
|
|
662
662
|
const target = structure2(node.name, node.description ?? "", past);
|
|
@@ -848,14 +848,14 @@ ${text}`;
|
|
|
848
848
|
if (org) await rt.link(node, await resolve(org), "ownership", "project");
|
|
849
849
|
return ok(node, "launch");
|
|
850
850
|
},
|
|
851
|
-
async "project.scope"(
|
|
851
|
+
async "project.scope"(project3, scope2, id) {
|
|
852
852
|
validateGherkin(scope2);
|
|
853
|
-
const node = await rt.create(await resolve(
|
|
853
|
+
const node = await rt.create(await resolve(project3), scope, scope2, id);
|
|
854
854
|
return ok(node, "scope");
|
|
855
855
|
},
|
|
856
|
-
async "project.milestone"(
|
|
856
|
+
async "project.milestone"(project3, milestone2, id) {
|
|
857
857
|
validateGherkin(milestone2);
|
|
858
|
-
const node = await rt.create(await resolve(
|
|
858
|
+
const node = await rt.create(await resolve(project3), milestone, milestone2, id);
|
|
859
859
|
return ok(node, "milestone");
|
|
860
860
|
},
|
|
861
861
|
async "project.achieve"(milestone2) {
|
|
@@ -863,44 +863,44 @@ ${text}`;
|
|
|
863
863
|
await rt.tag(node, "done");
|
|
864
864
|
return ok(node, "achieve");
|
|
865
865
|
},
|
|
866
|
-
async "project.enroll"(
|
|
867
|
-
const projNode = await resolve(
|
|
866
|
+
async "project.enroll"(project3, individual2) {
|
|
867
|
+
const projNode = await resolve(project3);
|
|
868
868
|
await rt.link(projNode, await resolve(individual2), "participation", "participate");
|
|
869
869
|
return ok(projNode, "enroll");
|
|
870
870
|
},
|
|
871
|
-
async "project.remove"(
|
|
872
|
-
const projNode = await resolve(
|
|
871
|
+
async "project.remove"(project3, individual2) {
|
|
872
|
+
const projNode = await resolve(project3);
|
|
873
873
|
await rt.unlink(projNode, await resolve(individual2), "participation", "participate");
|
|
874
874
|
return ok(projNode, "remove");
|
|
875
875
|
},
|
|
876
|
-
async "project.deliver"(
|
|
876
|
+
async "project.deliver"(project3, deliverable2, id) {
|
|
877
877
|
validateGherkin(deliverable2);
|
|
878
|
-
const node = await rt.create(await resolve(
|
|
878
|
+
const node = await rt.create(await resolve(project3), deliverable, deliverable2, id);
|
|
879
879
|
return ok(node, "deliver");
|
|
880
880
|
},
|
|
881
|
-
async "project.wiki"(
|
|
881
|
+
async "project.wiki"(project3, wiki2, id) {
|
|
882
882
|
validateGherkin(wiki2);
|
|
883
|
-
const node = await rt.create(await resolve(
|
|
883
|
+
const node = await rt.create(await resolve(project3), wiki, wiki2, id);
|
|
884
884
|
return ok(node, "wiki");
|
|
885
885
|
},
|
|
886
|
-
async "project.archive"(
|
|
887
|
-
return archive2(await resolve(
|
|
886
|
+
async "project.archive"(project3) {
|
|
887
|
+
return archive2(await resolve(project3), "archive");
|
|
888
888
|
},
|
|
889
|
-
async "project.produce"(
|
|
889
|
+
async "project.produce"(project3, content, id, alias) {
|
|
890
890
|
validateGherkin(content);
|
|
891
|
-
const projNode = await resolve(
|
|
891
|
+
const projNode = await resolve(project3);
|
|
892
892
|
const node = await rt.create(society2, product, content, id, alias);
|
|
893
893
|
await rt.link(projNode, node, "production", "produce");
|
|
894
894
|
await rt.link(node, projNode, "origin", "produced-by");
|
|
895
895
|
return ok(node, "produce");
|
|
896
896
|
},
|
|
897
|
-
async "project.maintain"(
|
|
898
|
-
const projNode = await resolve(
|
|
897
|
+
async "project.maintain"(project3, individual2) {
|
|
898
|
+
const projNode = await resolve(project3);
|
|
899
899
|
await rt.link(projNode, await resolve(individual2), "maintain", "maintained-by");
|
|
900
900
|
return ok(projNode, "maintain");
|
|
901
901
|
},
|
|
902
|
-
async "project.unmaintain"(
|
|
903
|
-
const projNode = await resolve(
|
|
902
|
+
async "project.unmaintain"(project3, individual2) {
|
|
903
|
+
const projNode = await resolve(project3);
|
|
904
904
|
await rt.unlink(projNode, await resolve(individual2), "maintain", "maintained-by");
|
|
905
905
|
return ok(projNode, "unmaintain");
|
|
906
906
|
},
|
|
@@ -1019,7 +1019,7 @@ ${text}`;
|
|
|
1019
1019
|
// ---- Census ----
|
|
1020
1020
|
async "census.list"(type) {
|
|
1021
1021
|
const target = type === "past" ? past2 : society2;
|
|
1022
|
-
const state = await
|
|
1022
|
+
const state = await project2(target);
|
|
1023
1023
|
const children = state.children ?? [];
|
|
1024
1024
|
const filtered = type === "past" ? children : children.filter((c) => type ? c.name === type : c.name !== "past");
|
|
1025
1025
|
return { state: { ...state, children: filtered }, process: "list" };
|
|
@@ -2832,6 +2832,14 @@ var sovereignPermissions = [
|
|
|
2832
2832
|
];
|
|
2833
2833
|
|
|
2834
2834
|
// src/projection.ts
|
|
2835
|
+
var DEFAULT_DEPTH = 1;
|
|
2836
|
+
function createProjection(rt, permissions) {
|
|
2837
|
+
return async (node, ctx) => {
|
|
2838
|
+
const raw = await rt.project(node);
|
|
2839
|
+
const compacted = compactState(raw, ctx?.depth ?? DEFAULT_DEPTH);
|
|
2840
|
+
return permissions.enrich(compacted);
|
|
2841
|
+
};
|
|
2842
|
+
}
|
|
2835
2843
|
var compactRelations = /* @__PURE__ */ new Set([
|
|
2836
2844
|
"crowned",
|
|
2837
2845
|
"belong",
|
|
@@ -2844,8 +2852,8 @@ function compact(state) {
|
|
|
2844
2852
|
const { children, links, ...node } = state;
|
|
2845
2853
|
return node;
|
|
2846
2854
|
}
|
|
2847
|
-
function compactState(state) {
|
|
2848
|
-
const children = state.children?.map((c) => compactState(c));
|
|
2855
|
+
function compactState(state, depth) {
|
|
2856
|
+
const children = depth > 0 ? state.children?.map((c) => compactState(c, depth - 1)) : state.children?.map((c) => compact(c));
|
|
2849
2857
|
const compactedLinks = state.links?.map(
|
|
2850
2858
|
(l) => compactRelations.has(l.relation) ? { ...l, target: compact(l.target) } : { ...l, target: compactLinkedTarget(l.target) }
|
|
2851
2859
|
);
|
|
@@ -2867,6 +2875,7 @@ function compactLinkedTarget(state) {
|
|
|
2867
2875
|
var RoleXService = class _RoleXService {
|
|
2868
2876
|
rt;
|
|
2869
2877
|
commands;
|
|
2878
|
+
project;
|
|
2870
2879
|
resourcex;
|
|
2871
2880
|
issuex;
|
|
2872
2881
|
repo;
|
|
@@ -2901,11 +2910,10 @@ var RoleXService = class _RoleXService {
|
|
|
2901
2910
|
return service;
|
|
2902
2911
|
}
|
|
2903
2912
|
async init() {
|
|
2904
|
-
|
|
2905
|
-
this.rt.project = async (node) => this.permissions.enrich(compactState(await originalProject(node)));
|
|
2913
|
+
this.project = createProjection(this.rt, this.permissions);
|
|
2906
2914
|
const roots = await this.rt.roots();
|
|
2907
2915
|
this.society = roots.find((r) => r.name === "society") ?? await this.rt.create(null, society);
|
|
2908
|
-
const societyState = await this.
|
|
2916
|
+
const societyState = await this.project(this.society);
|
|
2909
2917
|
const existingPast = societyState.children?.find((c) => c.name === "past");
|
|
2910
2918
|
this.past = existingPast ?? await this.rt.create(this.society, past);
|
|
2911
2919
|
this.commands = createCommands({
|
|
@@ -2918,6 +2926,7 @@ var RoleXService = class _RoleXService {
|
|
|
2918
2926
|
return node;
|
|
2919
2927
|
},
|
|
2920
2928
|
find: (id) => this.find(id),
|
|
2929
|
+
project: this.project,
|
|
2921
2930
|
resourcex: this.resourcex,
|
|
2922
2931
|
issuex: this.issuex,
|
|
2923
2932
|
prototype: this.repo.prototype,
|
|
@@ -2939,13 +2948,13 @@ var RoleXService = class _RoleXService {
|
|
|
2939
2948
|
const cached = this.roles.get(individual2);
|
|
2940
2949
|
if (cached) {
|
|
2941
2950
|
const node2 = await this.findOrAutoBorn(individual2);
|
|
2942
|
-
const state2 = await this.
|
|
2951
|
+
const state2 = await this.project(node2);
|
|
2943
2952
|
cached.hydrate(state2);
|
|
2944
2953
|
await this.restoreSnapshot(cached);
|
|
2945
2954
|
return cached;
|
|
2946
2955
|
}
|
|
2947
2956
|
const node = await this.findOrAutoBorn(individual2);
|
|
2948
|
-
const state = await this.
|
|
2957
|
+
const state = await this.project(node);
|
|
2949
2958
|
const role = new Role(individual2, {
|
|
2950
2959
|
commands: this.commands,
|
|
2951
2960
|
renderer: this.renderer,
|
|
@@ -2995,7 +3004,9 @@ var RoleXService = class _RoleXService {
|
|
|
2995
3004
|
// inspect — project any node's subtree
|
|
2996
3005
|
// ================================================================
|
|
2997
3006
|
async inspect(id) {
|
|
2998
|
-
const
|
|
3007
|
+
const node = await this.find(id);
|
|
3008
|
+
if (!node) throw new Error(`"${id}" not found.`);
|
|
3009
|
+
const state = await this.project(node);
|
|
2999
3010
|
const result = { state, process: "inspect" };
|
|
3000
3011
|
return this.renderer.render("inspect", result);
|
|
3001
3012
|
}
|
|
@@ -3004,7 +3015,7 @@ var RoleXService = class _RoleXService {
|
|
|
3004
3015
|
// ================================================================
|
|
3005
3016
|
async survey(type) {
|
|
3006
3017
|
const target = type === "past" ? this.past : this.society;
|
|
3007
|
-
const state = await this.
|
|
3018
|
+
const state = await this.project(target);
|
|
3008
3019
|
const children = state.children ?? [];
|
|
3009
3020
|
const filtered = type === "past" ? children : children.filter((c) => type ? c.name === type : c.name !== "past");
|
|
3010
3021
|
const result = { state: { ...state, children: filtered }, process: "list" };
|
|
@@ -3040,16 +3051,10 @@ You may be guessing the command name. Load the relevant skill first with skill(l
|
|
|
3040
3051
|
// ================================================================
|
|
3041
3052
|
// Internal helpers
|
|
3042
3053
|
// ================================================================
|
|
3043
|
-
/** Find a node by id across the entire society tree. */
|
|
3054
|
+
/** Find a node by id across the entire society tree (raw, no pipeline). */
|
|
3044
3055
|
async find(id) {
|
|
3045
|
-
const
|
|
3046
|
-
return findInState(
|
|
3047
|
-
}
|
|
3048
|
-
/** Find and project a node's full subtree by id. */
|
|
3049
|
-
async projectById(id) {
|
|
3050
|
-
const node = await this.find(id);
|
|
3051
|
-
if (!node) throw new Error(`"${id}" not found.`);
|
|
3052
|
-
return this.rt.project(node);
|
|
3056
|
+
const raw = await this.rt.project(this.society);
|
|
3057
|
+
return findInState(raw, id);
|
|
3053
3058
|
}
|
|
3054
3059
|
};
|
|
3055
3060
|
function isCommandResult(value) {
|