@polintpro/proposit-core 0.6.6 → 0.7.5
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 +201 -0
- package/dist/extensions/basics/schemata.d.ts +7 -0
- package/dist/extensions/basics/schemata.d.ts.map +1 -1
- package/dist/lib/consts.d.ts.map +1 -1
- package/dist/lib/consts.js +34 -2
- package/dist/lib/consts.js.map +1 -1
- package/dist/lib/core/argument-engine.d.ts +38 -2
- package/dist/lib/core/argument-engine.d.ts.map +1 -1
- package/dist/lib/core/argument-engine.js +636 -227
- package/dist/lib/core/argument-engine.js.map +1 -1
- package/dist/lib/core/change-collector.d.ts +1 -0
- package/dist/lib/core/change-collector.d.ts.map +1 -1
- package/dist/lib/core/change-collector.js +3 -0
- package/dist/lib/core/change-collector.js.map +1 -1
- package/dist/lib/core/claim-library.d.ts +4 -0
- package/dist/lib/core/claim-library.d.ts.map +1 -1
- package/dist/lib/core/claim-library.js +126 -59
- package/dist/lib/core/claim-library.js.map +1 -1
- package/dist/lib/core/claim-source-library.d.ts +4 -0
- package/dist/lib/core/claim-source-library.d.ts.map +1 -1
- package/dist/lib/core/claim-source-library.js +114 -38
- package/dist/lib/core/claim-source-library.js.map +1 -1
- package/dist/lib/core/diff.d.ts +10 -0
- package/dist/lib/core/diff.d.ts.map +1 -1
- package/dist/lib/core/diff.js +114 -21
- package/dist/lib/core/diff.js.map +1 -1
- package/dist/lib/core/expression-manager.d.ts +11 -0
- package/dist/lib/core/expression-manager.d.ts.map +1 -1
- package/dist/lib/core/expression-manager.js +379 -20
- package/dist/lib/core/expression-manager.js.map +1 -1
- package/dist/lib/core/fork.d.ts +31 -0
- package/dist/lib/core/fork.d.ts.map +1 -0
- package/dist/lib/core/fork.js +139 -0
- package/dist/lib/core/fork.js.map +1 -0
- package/dist/lib/core/forks-library.d.ts +58 -0
- package/dist/lib/core/forks-library.d.ts.map +1 -0
- package/dist/lib/core/forks-library.js +142 -0
- package/dist/lib/core/forks-library.js.map +1 -0
- package/dist/lib/core/interfaces/argument-engine.interfaces.d.ts +9 -2
- package/dist/lib/core/interfaces/argument-engine.interfaces.d.ts.map +1 -1
- package/dist/lib/core/interfaces/index.d.ts +1 -1
- package/dist/lib/core/interfaces/index.d.ts.map +1 -1
- package/dist/lib/core/interfaces/library.interfaces.d.ts +48 -0
- package/dist/lib/core/interfaces/library.interfaces.d.ts.map +1 -1
- package/dist/lib/core/interfaces/premise-engine.interfaces.d.ts +22 -0
- package/dist/lib/core/interfaces/premise-engine.interfaces.d.ts.map +1 -1
- package/dist/lib/core/invariant-violation-error.d.ts +6 -0
- package/dist/lib/core/invariant-violation-error.d.ts.map +1 -0
- package/dist/lib/core/invariant-violation-error.js +12 -0
- package/dist/lib/core/invariant-violation-error.js.map +1 -0
- package/dist/lib/core/parser/formula.d.ts.map +1 -1
- package/dist/lib/core/parser/formula.js +2 -2
- package/dist/lib/core/parser/formula.js.map +1 -1
- package/dist/lib/core/premise-engine.d.ts +10 -0
- package/dist/lib/core/premise-engine.d.ts.map +1 -1
- package/dist/lib/core/premise-engine.js +699 -536
- package/dist/lib/core/premise-engine.js.map +1 -1
- package/dist/lib/core/source-library.d.ts +4 -0
- package/dist/lib/core/source-library.d.ts.map +1 -1
- package/dist/lib/core/source-library.js +126 -59
- package/dist/lib/core/source-library.js.map +1 -1
- package/dist/lib/core/variable-manager.d.ts +7 -0
- package/dist/lib/core/variable-manager.d.ts.map +1 -1
- package/dist/lib/core/variable-manager.js +65 -1
- package/dist/lib/core/variable-manager.js.map +1 -1
- package/dist/lib/index.d.ts +9 -1
- package/dist/lib/index.d.ts.map +1 -1
- package/dist/lib/index.js +8 -1
- package/dist/lib/index.js.map +1 -1
- package/dist/lib/schemata/argument.d.ts +3 -0
- package/dist/lib/schemata/argument.d.ts.map +1 -1
- package/dist/lib/schemata/argument.js +9 -0
- package/dist/lib/schemata/argument.js.map +1 -1
- package/dist/lib/schemata/fork.d.ts +17 -0
- package/dist/lib/schemata/fork.d.ts.map +1 -0
- package/dist/lib/schemata/fork.js +27 -0
- package/dist/lib/schemata/fork.js.map +1 -0
- package/dist/lib/schemata/index.d.ts +1 -0
- package/dist/lib/schemata/index.d.ts.map +1 -1
- package/dist/lib/schemata/index.js +1 -0
- package/dist/lib/schemata/index.js.map +1 -1
- package/dist/lib/schemata/propositional.d.ts +52 -0
- package/dist/lib/schemata/propositional.d.ts.map +1 -1
- package/dist/lib/schemata/propositional.js +43 -0
- package/dist/lib/schemata/propositional.js.map +1 -1
- package/dist/lib/types/checksum.d.ts +2 -0
- package/dist/lib/types/checksum.d.ts.map +1 -1
- package/dist/lib/types/diff.d.ts +6 -0
- package/dist/lib/types/diff.d.ts.map +1 -1
- package/dist/lib/types/fork.d.ts +25 -0
- package/dist/lib/types/fork.d.ts.map +1 -0
- package/dist/lib/types/fork.js +2 -0
- package/dist/lib/types/fork.js.map +1 -0
- package/dist/lib/types/grammar.d.ts +5 -4
- package/dist/lib/types/grammar.d.ts.map +1 -1
- package/dist/lib/types/grammar.js.map +1 -1
- package/dist/lib/types/validation.d.ts +47 -0
- package/dist/lib/types/validation.d.ts.map +1 -0
- package/dist/lib/types/validation.js +43 -0
- package/dist/lib/types/validation.js.map +1 -0
- package/dist/lib/utils/changeset.d.ts +124 -0
- package/dist/lib/utils/changeset.d.ts.map +1 -0
- package/dist/lib/utils/changeset.js +221 -0
- package/dist/lib/utils/changeset.js.map +1 -0
- package/dist/lib/utils/lookup.d.ts +47 -0
- package/dist/lib/utils/lookup.d.ts.map +1 -0
- package/dist/lib/utils/lookup.js +62 -0
- package/dist/lib/utils/lookup.js.map +1 -0
- package/package.json +1 -1
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
// -- Expression-level codes --
|
|
2
|
+
export const EXPR_SCHEMA_INVALID = "EXPR_SCHEMA_INVALID";
|
|
3
|
+
export const EXPR_DUPLICATE_ID = "EXPR_DUPLICATE_ID";
|
|
4
|
+
export const EXPR_SELF_REFERENTIAL_PARENT = "EXPR_SELF_REFERENTIAL_PARENT";
|
|
5
|
+
export const EXPR_PARENT_NOT_FOUND = "EXPR_PARENT_NOT_FOUND";
|
|
6
|
+
export const EXPR_PARENT_NOT_CONTAINER = "EXPR_PARENT_NOT_CONTAINER";
|
|
7
|
+
export const EXPR_ROOT_ONLY_VIOLATED = "EXPR_ROOT_ONLY_VIOLATED";
|
|
8
|
+
export const EXPR_FORMULA_BETWEEN_OPERATORS_VIOLATED = "EXPR_FORMULA_BETWEEN_OPERATORS_VIOLATED";
|
|
9
|
+
export const EXPR_CHILD_LIMIT_EXCEEDED = "EXPR_CHILD_LIMIT_EXCEEDED";
|
|
10
|
+
export const EXPR_POSITION_DUPLICATE = "EXPR_POSITION_DUPLICATE";
|
|
11
|
+
export const EXPR_CHECKSUM_MISMATCH = "EXPR_CHECKSUM_MISMATCH";
|
|
12
|
+
// -- Premise-level codes --
|
|
13
|
+
export const PREMISE_SCHEMA_INVALID = "PREMISE_SCHEMA_INVALID";
|
|
14
|
+
export const PREMISE_ROOT_EXPRESSION_INVALID = "PREMISE_ROOT_EXPRESSION_INVALID";
|
|
15
|
+
export const PREMISE_VARIABLE_REF_NOT_FOUND = "PREMISE_VARIABLE_REF_NOT_FOUND";
|
|
16
|
+
export const PREMISE_CHECKSUM_MISMATCH = "PREMISE_CHECKSUM_MISMATCH";
|
|
17
|
+
// -- Variable-level codes --
|
|
18
|
+
export const VAR_SCHEMA_INVALID = "VAR_SCHEMA_INVALID";
|
|
19
|
+
export const VAR_DUPLICATE_ID = "VAR_DUPLICATE_ID";
|
|
20
|
+
export const VAR_DUPLICATE_SYMBOL = "VAR_DUPLICATE_SYMBOL";
|
|
21
|
+
export const VAR_CHECKSUM_MISMATCH = "VAR_CHECKSUM_MISMATCH";
|
|
22
|
+
// -- Argument-level codes --
|
|
23
|
+
export const ARG_SCHEMA_INVALID = "ARG_SCHEMA_INVALID";
|
|
24
|
+
export const ARG_OWNERSHIP_MISMATCH = "ARG_OWNERSHIP_MISMATCH";
|
|
25
|
+
export const ARG_CLAIM_REF_NOT_FOUND = "ARG_CLAIM_REF_NOT_FOUND";
|
|
26
|
+
export const ARG_PREMISE_REF_NOT_FOUND = "ARG_PREMISE_REF_NOT_FOUND";
|
|
27
|
+
export const ARG_CIRCULARITY_DETECTED = "ARG_CIRCULARITY_DETECTED";
|
|
28
|
+
export const ARG_CONCLUSION_NOT_FOUND = "ARG_CONCLUSION_NOT_FOUND";
|
|
29
|
+
export const ARG_CHECKSUM_MISMATCH = "ARG_CHECKSUM_MISMATCH";
|
|
30
|
+
// -- ClaimLibrary codes --
|
|
31
|
+
export const CLAIM_SCHEMA_INVALID = "CLAIM_SCHEMA_INVALID";
|
|
32
|
+
export const CLAIM_FROZEN_NO_SUCCESSOR = "CLAIM_FROZEN_NO_SUCCESSOR";
|
|
33
|
+
// -- SourceLibrary codes --
|
|
34
|
+
export const SOURCE_SCHEMA_INVALID = "SOURCE_SCHEMA_INVALID";
|
|
35
|
+
export const SOURCE_FROZEN_NO_SUCCESSOR = "SOURCE_FROZEN_NO_SUCCESSOR";
|
|
36
|
+
// -- ClaimSourceLibrary codes --
|
|
37
|
+
export const ASSOC_SCHEMA_INVALID = "ASSOC_SCHEMA_INVALID";
|
|
38
|
+
export const ASSOC_DUPLICATE_ID = "ASSOC_DUPLICATE_ID";
|
|
39
|
+
export const ASSOC_CLAIM_REF_NOT_FOUND = "ASSOC_CLAIM_REF_NOT_FOUND";
|
|
40
|
+
export const ASSOC_SOURCE_REF_NOT_FOUND = "ASSOC_SOURCE_REF_NOT_FOUND";
|
|
41
|
+
// -- ForksLibrary codes --
|
|
42
|
+
export const FORK_SCHEMA_INVALID = "FORK_SCHEMA_INVALID";
|
|
43
|
+
//# sourceMappingURL=validation.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validation.js","sourceRoot":"","sources":["../../../src/lib/types/validation.ts"],"names":[],"mappings":"AAuBA,+BAA+B;AAC/B,MAAM,CAAC,MAAM,mBAAmB,GAAG,qBAAqB,CAAA;AACxD,MAAM,CAAC,MAAM,iBAAiB,GAAG,mBAAmB,CAAA;AACpD,MAAM,CAAC,MAAM,4BAA4B,GAAG,8BAA8B,CAAA;AAC1E,MAAM,CAAC,MAAM,qBAAqB,GAAG,uBAAuB,CAAA;AAC5D,MAAM,CAAC,MAAM,yBAAyB,GAAG,2BAA2B,CAAA;AACpE,MAAM,CAAC,MAAM,uBAAuB,GAAG,yBAAyB,CAAA;AAChE,MAAM,CAAC,MAAM,uCAAuC,GAChD,yCAAyC,CAAA;AAC7C,MAAM,CAAC,MAAM,yBAAyB,GAAG,2BAA2B,CAAA;AACpE,MAAM,CAAC,MAAM,uBAAuB,GAAG,yBAAyB,CAAA;AAChE,MAAM,CAAC,MAAM,sBAAsB,GAAG,wBAAwB,CAAA;AAE9D,4BAA4B;AAC5B,MAAM,CAAC,MAAM,sBAAsB,GAAG,wBAAwB,CAAA;AAC9D,MAAM,CAAC,MAAM,+BAA+B,GAAG,iCAAiC,CAAA;AAChF,MAAM,CAAC,MAAM,8BAA8B,GAAG,gCAAgC,CAAA;AAC9E,MAAM,CAAC,MAAM,yBAAyB,GAAG,2BAA2B,CAAA;AAEpE,6BAA6B;AAC7B,MAAM,CAAC,MAAM,kBAAkB,GAAG,oBAAoB,CAAA;AACtD,MAAM,CAAC,MAAM,gBAAgB,GAAG,kBAAkB,CAAA;AAClD,MAAM,CAAC,MAAM,oBAAoB,GAAG,sBAAsB,CAAA;AAC1D,MAAM,CAAC,MAAM,qBAAqB,GAAG,uBAAuB,CAAA;AAE5D,6BAA6B;AAC7B,MAAM,CAAC,MAAM,kBAAkB,GAAG,oBAAoB,CAAA;AACtD,MAAM,CAAC,MAAM,sBAAsB,GAAG,wBAAwB,CAAA;AAC9D,MAAM,CAAC,MAAM,uBAAuB,GAAG,yBAAyB,CAAA;AAChE,MAAM,CAAC,MAAM,yBAAyB,GAAG,2BAA2B,CAAA;AACpE,MAAM,CAAC,MAAM,wBAAwB,GAAG,0BAA0B,CAAA;AAClE,MAAM,CAAC,MAAM,wBAAwB,GAAG,0BAA0B,CAAA;AAClE,MAAM,CAAC,MAAM,qBAAqB,GAAG,uBAAuB,CAAA;AAE5D,2BAA2B;AAC3B,MAAM,CAAC,MAAM,oBAAoB,GAAG,sBAAsB,CAAA;AAC1D,MAAM,CAAC,MAAM,yBAAyB,GAAG,2BAA2B,CAAA;AAEpE,4BAA4B;AAC5B,MAAM,CAAC,MAAM,qBAAqB,GAAG,uBAAuB,CAAA;AAC5D,MAAM,CAAC,MAAM,0BAA0B,GAAG,4BAA4B,CAAA;AAEtE,iCAAiC;AACjC,MAAM,CAAC,MAAM,oBAAoB,GAAG,sBAAsB,CAAA;AAC1D,MAAM,CAAC,MAAM,kBAAkB,GAAG,oBAAoB,CAAA;AACtD,MAAM,CAAC,MAAM,yBAAyB,GAAG,2BAA2B,CAAA;AACpE,MAAM,CAAC,MAAM,0BAA0B,GAAG,4BAA4B,CAAA;AAEtE,2BAA2B;AAC3B,MAAM,CAAC,MAAM,mBAAmB,GAAG,qBAAqB,CAAA"}
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
import type { TCorePropositionalExpression, TCorePropositionalVariable, TCorePremise } from "../schemata/propositional.js";
|
|
2
|
+
import type { TCoreArgument, TCoreArgumentRoleState } from "../schemata/argument.js";
|
|
3
|
+
import type { TCoreChangeset } from "../types/mutation.js";
|
|
4
|
+
/**
|
|
5
|
+
* Merges two changesets into one, deduplicating entities by `id` within each
|
|
6
|
+
* bucket (added/modified/removed) with last-write-wins semantics.
|
|
7
|
+
*
|
|
8
|
+
* Use this when a single logical operation requires multiple engine calls that
|
|
9
|
+
* each produce a changeset. For example, creating a conclusion premise requires
|
|
10
|
+
* both `createPremiseWithId` and `setConclusionPremise`, each returning a
|
|
11
|
+
* changeset — `mergeChangesets` combines them into one changeset suitable for
|
|
12
|
+
* a single persistence call.
|
|
13
|
+
*
|
|
14
|
+
* @param a - The first changeset.
|
|
15
|
+
* @param b - The second changeset. Its entries take precedence when both
|
|
16
|
+
* changesets contain the same entity ID in the same bucket.
|
|
17
|
+
* @returns A merged changeset. Entity categories that are empty after merge
|
|
18
|
+
* are omitted from the result.
|
|
19
|
+
* @throws {Error} If any entity ID appears in more than one bucket
|
|
20
|
+
* (added/modified/removed) within the same category after merge. This
|
|
21
|
+
* indicates a logic error in the caller.
|
|
22
|
+
*
|
|
23
|
+
* @example
|
|
24
|
+
* ```ts
|
|
25
|
+
* const { changes: createChanges } = engine.createPremiseWithId(premiseId, data)
|
|
26
|
+
* const { changes: roleChanges } = engine.setConclusionPremise(premiseId)
|
|
27
|
+
* const combined = mergeChangesets(createChanges, roleChanges)
|
|
28
|
+
* await persistChangeset(db, combined)
|
|
29
|
+
* ```
|
|
30
|
+
*/
|
|
31
|
+
export declare function mergeChangesets<TExpr extends TCorePropositionalExpression = TCorePropositionalExpression, TVar extends TCorePropositionalVariable = TCorePropositionalVariable, TPremise extends TCorePremise = TCorePremise, TArg extends TCoreArgument = TCoreArgument>(a: TCoreChangeset<TExpr, TVar, TPremise, TArg>, b: TCoreChangeset<TExpr, TVar, TPremise, TArg>): TCoreChangeset<TExpr, TVar, TPremise, TArg>;
|
|
32
|
+
/**
|
|
33
|
+
* A single persistence operation extracted from a changeset, tagged with
|
|
34
|
+
* its operation type (`insert`, `update`, or `delete`) and entity kind.
|
|
35
|
+
*
|
|
36
|
+
* Used as the element type for the ordered operation list returned by
|
|
37
|
+
* {@link orderChangeset}.
|
|
38
|
+
*/
|
|
39
|
+
export type TOrderedOperation<TExpr extends TCorePropositionalExpression = TCorePropositionalExpression, TVar extends TCorePropositionalVariable = TCorePropositionalVariable, TPremise extends TCorePremise = TCorePremise, TArg extends TCoreArgument = TCoreArgument> = {
|
|
40
|
+
type: "delete";
|
|
41
|
+
entity: "expression";
|
|
42
|
+
data: TExpr;
|
|
43
|
+
} | {
|
|
44
|
+
type: "delete";
|
|
45
|
+
entity: "variable";
|
|
46
|
+
data: TVar;
|
|
47
|
+
} | {
|
|
48
|
+
type: "delete";
|
|
49
|
+
entity: "premise";
|
|
50
|
+
data: TPremise;
|
|
51
|
+
} | {
|
|
52
|
+
type: "insert";
|
|
53
|
+
entity: "premise";
|
|
54
|
+
data: TPremise;
|
|
55
|
+
} | {
|
|
56
|
+
type: "insert";
|
|
57
|
+
entity: "variable";
|
|
58
|
+
data: TVar;
|
|
59
|
+
} | {
|
|
60
|
+
type: "insert";
|
|
61
|
+
entity: "expression";
|
|
62
|
+
data: TExpr;
|
|
63
|
+
} | {
|
|
64
|
+
type: "update";
|
|
65
|
+
entity: "expression";
|
|
66
|
+
data: TExpr;
|
|
67
|
+
} | {
|
|
68
|
+
type: "update";
|
|
69
|
+
entity: "variable";
|
|
70
|
+
data: TVar;
|
|
71
|
+
} | {
|
|
72
|
+
type: "update";
|
|
73
|
+
entity: "premise";
|
|
74
|
+
data: TPremise;
|
|
75
|
+
} | {
|
|
76
|
+
type: "update";
|
|
77
|
+
entity: "argument";
|
|
78
|
+
data: TArg;
|
|
79
|
+
} | {
|
|
80
|
+
type: "update";
|
|
81
|
+
entity: "roles";
|
|
82
|
+
data: TCoreArgumentRoleState;
|
|
83
|
+
};
|
|
84
|
+
/**
|
|
85
|
+
* Converts a changeset into a flat, ordered array of persistence operations
|
|
86
|
+
* that is safe to execute sequentially against a relational store with
|
|
87
|
+
* foreign-key constraints.
|
|
88
|
+
*
|
|
89
|
+
* The FK dependency chain is:
|
|
90
|
+
* - `expression.premiseId` → `premise.id`
|
|
91
|
+
* - `expression.variableId` → `variable.id` (for variable-type expressions)
|
|
92
|
+
* - `expression.parentId` → `expression.id` (self-FK for tree structure)
|
|
93
|
+
* - `variable.argumentId` → `argument.id`
|
|
94
|
+
* - `premise.argumentId` → `argument.id`
|
|
95
|
+
*
|
|
96
|
+
* The resulting order guarantees that every referenced row exists before any
|
|
97
|
+
* row that depends on it is inserted, and that every dependent row is removed
|
|
98
|
+
* before the row it references is deleted.
|
|
99
|
+
*
|
|
100
|
+
* Ordering phases:
|
|
101
|
+
* 1. Update premises — ensure premise rows have correct metadata before
|
|
102
|
+
* dependent deletes run.
|
|
103
|
+
* 2. Delete expressions — expression rows hold FKs to variables and premises,
|
|
104
|
+
* so they must be removed first.
|
|
105
|
+
* 3. Delete variables — safe after expression deletes (no remaining FK
|
|
106
|
+
* references from expressions).
|
|
107
|
+
* 4. Delete premises — safe after all child rows are removed.
|
|
108
|
+
* 5. Insert premises — new premises must exist before their expressions and
|
|
109
|
+
* variables can be inserted.
|
|
110
|
+
* 6. Insert variables — new variables must exist before variable-type
|
|
111
|
+
* expressions can reference them.
|
|
112
|
+
* 7. Insert expressions — topologically sorted so parent expressions are
|
|
113
|
+
* inserted before their children (satisfies the parentId self-FK).
|
|
114
|
+
* 8. Update variables — grouped after inserts for clarity.
|
|
115
|
+
* 9. Update expressions — checksum and position updates.
|
|
116
|
+
* 10. Update argument metadata — if present.
|
|
117
|
+
* 11. Update role state — if present.
|
|
118
|
+
*
|
|
119
|
+
* @param changeset - The changeset to convert into ordered operations.
|
|
120
|
+
* @returns A flat array of {@link TOrderedOperation} entries in FK-safe
|
|
121
|
+
* execution order. Returns an empty array if the changeset is empty.
|
|
122
|
+
*/
|
|
123
|
+
export declare function orderChangeset<TExpr extends TCorePropositionalExpression = TCorePropositionalExpression, TVar extends TCorePropositionalVariable = TCorePropositionalVariable, TPremise extends TCorePremise = TCorePremise, TArg extends TCoreArgument = TCoreArgument>(changeset: TCoreChangeset<TExpr, TVar, TPremise, TArg>): TOrderedOperation<TExpr, TVar, TPremise, TArg>[];
|
|
124
|
+
//# sourceMappingURL=changeset.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"changeset.d.ts","sourceRoot":"","sources":["../../../src/lib/utils/changeset.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,221 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Merges two changesets into one, deduplicating entities by `id` within each
|
|
3
|
+
* bucket (added/modified/removed) with last-write-wins semantics.
|
|
4
|
+
*
|
|
5
|
+
* Use this when a single logical operation requires multiple engine calls that
|
|
6
|
+
* each produce a changeset. For example, creating a conclusion premise requires
|
|
7
|
+
* both `createPremiseWithId` and `setConclusionPremise`, each returning a
|
|
8
|
+
* changeset — `mergeChangesets` combines them into one changeset suitable for
|
|
9
|
+
* a single persistence call.
|
|
10
|
+
*
|
|
11
|
+
* @param a - The first changeset.
|
|
12
|
+
* @param b - The second changeset. Its entries take precedence when both
|
|
13
|
+
* changesets contain the same entity ID in the same bucket.
|
|
14
|
+
* @returns A merged changeset. Entity categories that are empty after merge
|
|
15
|
+
* are omitted from the result.
|
|
16
|
+
* @throws {Error} If any entity ID appears in more than one bucket
|
|
17
|
+
* (added/modified/removed) within the same category after merge. This
|
|
18
|
+
* indicates a logic error in the caller.
|
|
19
|
+
*
|
|
20
|
+
* @example
|
|
21
|
+
* ```ts
|
|
22
|
+
* const { changes: createChanges } = engine.createPremiseWithId(premiseId, data)
|
|
23
|
+
* const { changes: roleChanges } = engine.setConclusionPremise(premiseId)
|
|
24
|
+
* const combined = mergeChangesets(createChanges, roleChanges)
|
|
25
|
+
* await persistChangeset(db, combined)
|
|
26
|
+
* ```
|
|
27
|
+
*/
|
|
28
|
+
export function mergeChangesets(a, b) {
|
|
29
|
+
const result = {};
|
|
30
|
+
const mergedExpressions = mergeEntityChanges(a.expressions, b.expressions, "expressions");
|
|
31
|
+
if (mergedExpressions)
|
|
32
|
+
result.expressions = mergedExpressions;
|
|
33
|
+
const mergedVariables = mergeEntityChanges(a.variables, b.variables, "variables");
|
|
34
|
+
if (mergedVariables)
|
|
35
|
+
result.variables = mergedVariables;
|
|
36
|
+
const mergedPremises = mergeEntityChanges(a.premises, b.premises, "premises");
|
|
37
|
+
if (mergedPremises)
|
|
38
|
+
result.premises = mergedPremises;
|
|
39
|
+
if (b.roles !== undefined) {
|
|
40
|
+
result.roles = b.roles;
|
|
41
|
+
}
|
|
42
|
+
else if (a.roles !== undefined) {
|
|
43
|
+
result.roles = a.roles;
|
|
44
|
+
}
|
|
45
|
+
if (b.argument !== undefined) {
|
|
46
|
+
result.argument = b.argument;
|
|
47
|
+
}
|
|
48
|
+
else if (a.argument !== undefined) {
|
|
49
|
+
result.argument = a.argument;
|
|
50
|
+
}
|
|
51
|
+
return result;
|
|
52
|
+
}
|
|
53
|
+
function mergeEntityChanges(a, b, categoryName) {
|
|
54
|
+
if (!a && !b)
|
|
55
|
+
return undefined;
|
|
56
|
+
const dedup = (aList, bList) => {
|
|
57
|
+
const map = new Map();
|
|
58
|
+
for (const item of aList)
|
|
59
|
+
map.set(item.id, item);
|
|
60
|
+
for (const item of bList)
|
|
61
|
+
map.set(item.id, item);
|
|
62
|
+
return [...map.values()];
|
|
63
|
+
};
|
|
64
|
+
const added = dedup(a?.added ?? [], b?.added ?? []);
|
|
65
|
+
const modified = dedup(a?.modified ?? [], b?.modified ?? []);
|
|
66
|
+
const removed = dedup(a?.removed ?? [], b?.removed ?? []);
|
|
67
|
+
// Enforce invariant: no entity ID may appear in more than one bucket.
|
|
68
|
+
const addedIds = new Set(added.map((e) => e.id));
|
|
69
|
+
const modifiedIds = new Set(modified.map((e) => e.id));
|
|
70
|
+
const removedIds = new Set(removed.map((e) => e.id));
|
|
71
|
+
for (const id of addedIds) {
|
|
72
|
+
if (modifiedIds.has(id)) {
|
|
73
|
+
throw new Error(`mergeChangesets: entity "${id}" appears in both added and modified in ${categoryName}`);
|
|
74
|
+
}
|
|
75
|
+
if (removedIds.has(id)) {
|
|
76
|
+
throw new Error(`mergeChangesets: entity "${id}" appears in both added and removed in ${categoryName}`);
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
for (const id of modifiedIds) {
|
|
80
|
+
if (removedIds.has(id)) {
|
|
81
|
+
throw new Error(`mergeChangesets: entity "${id}" appears in both modified and removed in ${categoryName}`);
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
if (added.length === 0 && modified.length === 0 && removed.length === 0) {
|
|
85
|
+
return undefined;
|
|
86
|
+
}
|
|
87
|
+
return { added, modified, removed };
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Converts a changeset into a flat, ordered array of persistence operations
|
|
91
|
+
* that is safe to execute sequentially against a relational store with
|
|
92
|
+
* foreign-key constraints.
|
|
93
|
+
*
|
|
94
|
+
* The FK dependency chain is:
|
|
95
|
+
* - `expression.premiseId` → `premise.id`
|
|
96
|
+
* - `expression.variableId` → `variable.id` (for variable-type expressions)
|
|
97
|
+
* - `expression.parentId` → `expression.id` (self-FK for tree structure)
|
|
98
|
+
* - `variable.argumentId` → `argument.id`
|
|
99
|
+
* - `premise.argumentId` → `argument.id`
|
|
100
|
+
*
|
|
101
|
+
* The resulting order guarantees that every referenced row exists before any
|
|
102
|
+
* row that depends on it is inserted, and that every dependent row is removed
|
|
103
|
+
* before the row it references is deleted.
|
|
104
|
+
*
|
|
105
|
+
* Ordering phases:
|
|
106
|
+
* 1. Update premises — ensure premise rows have correct metadata before
|
|
107
|
+
* dependent deletes run.
|
|
108
|
+
* 2. Delete expressions — expression rows hold FKs to variables and premises,
|
|
109
|
+
* so they must be removed first.
|
|
110
|
+
* 3. Delete variables — safe after expression deletes (no remaining FK
|
|
111
|
+
* references from expressions).
|
|
112
|
+
* 4. Delete premises — safe after all child rows are removed.
|
|
113
|
+
* 5. Insert premises — new premises must exist before their expressions and
|
|
114
|
+
* variables can be inserted.
|
|
115
|
+
* 6. Insert variables — new variables must exist before variable-type
|
|
116
|
+
* expressions can reference them.
|
|
117
|
+
* 7. Insert expressions — topologically sorted so parent expressions are
|
|
118
|
+
* inserted before their children (satisfies the parentId self-FK).
|
|
119
|
+
* 8. Update variables — grouped after inserts for clarity.
|
|
120
|
+
* 9. Update expressions — checksum and position updates.
|
|
121
|
+
* 10. Update argument metadata — if present.
|
|
122
|
+
* 11. Update role state — if present.
|
|
123
|
+
*
|
|
124
|
+
* @param changeset - The changeset to convert into ordered operations.
|
|
125
|
+
* @returns A flat array of {@link TOrderedOperation} entries in FK-safe
|
|
126
|
+
* execution order. Returns an empty array if the changeset is empty.
|
|
127
|
+
*/
|
|
128
|
+
export function orderChangeset(changeset) {
|
|
129
|
+
const ops = [];
|
|
130
|
+
// Phase 1: Update premises — ensure premise rows have correct metadata
|
|
131
|
+
// before dependent deletes run.
|
|
132
|
+
for (const p of changeset.premises?.modified ?? []) {
|
|
133
|
+
ops.push({ type: "update", entity: "premise", data: p });
|
|
134
|
+
}
|
|
135
|
+
// Phase 2: Delete expressions — reverse-topologically sorted so children
|
|
136
|
+
// are deleted before parents (satisfies the parentId self-FK).
|
|
137
|
+
const removedExprs = changeset.expressions?.removed ?? [];
|
|
138
|
+
const sortedRemoved = topologicalSortExpressions(removedExprs).reverse();
|
|
139
|
+
for (const e of sortedRemoved) {
|
|
140
|
+
ops.push({ type: "delete", entity: "expression", data: e });
|
|
141
|
+
}
|
|
142
|
+
// Phase 3: Delete variables — safe after expression deletes (no
|
|
143
|
+
// remaining FK references from expressions).
|
|
144
|
+
for (const v of changeset.variables?.removed ?? []) {
|
|
145
|
+
ops.push({ type: "delete", entity: "variable", data: v });
|
|
146
|
+
}
|
|
147
|
+
// Phase 4: Delete premises — safe after all child rows (expressions,
|
|
148
|
+
// variables) are removed.
|
|
149
|
+
for (const p of changeset.premises?.removed ?? []) {
|
|
150
|
+
ops.push({ type: "delete", entity: "premise", data: p });
|
|
151
|
+
}
|
|
152
|
+
// Phase 5: Insert premises — new premises must exist before their
|
|
153
|
+
// expressions and variables can be inserted.
|
|
154
|
+
for (const p of changeset.premises?.added ?? []) {
|
|
155
|
+
ops.push({ type: "insert", entity: "premise", data: p });
|
|
156
|
+
}
|
|
157
|
+
// Phase 6: Insert variables — new variables must exist before
|
|
158
|
+
// variable-type expressions can reference them.
|
|
159
|
+
for (const v of changeset.variables?.added ?? []) {
|
|
160
|
+
ops.push({ type: "insert", entity: "variable", data: v });
|
|
161
|
+
}
|
|
162
|
+
// Phase 7: Insert expressions — topologically sorted so parent
|
|
163
|
+
// expressions are inserted before their children (satisfies the
|
|
164
|
+
// parentId self-FK).
|
|
165
|
+
const sortedInsertExprs = topologicalSortExpressions(changeset.expressions?.added ?? []);
|
|
166
|
+
for (const e of sortedInsertExprs) {
|
|
167
|
+
ops.push({ type: "insert", entity: "expression", data: e });
|
|
168
|
+
}
|
|
169
|
+
// Phase 8: Update variables — grouped after inserts for clarity.
|
|
170
|
+
for (const v of changeset.variables?.modified ?? []) {
|
|
171
|
+
ops.push({ type: "update", entity: "variable", data: v });
|
|
172
|
+
}
|
|
173
|
+
// Phase 9: Update expressions — checksum and position updates.
|
|
174
|
+
for (const e of changeset.expressions?.modified ?? []) {
|
|
175
|
+
ops.push({ type: "update", entity: "expression", data: e });
|
|
176
|
+
}
|
|
177
|
+
// Phase 10: Update argument metadata — if present.
|
|
178
|
+
if (changeset.argument !== undefined) {
|
|
179
|
+
ops.push({
|
|
180
|
+
type: "update",
|
|
181
|
+
entity: "argument",
|
|
182
|
+
data: changeset.argument,
|
|
183
|
+
});
|
|
184
|
+
}
|
|
185
|
+
// Phase 11: Update role state — if present.
|
|
186
|
+
if (changeset.roles !== undefined) {
|
|
187
|
+
ops.push({ type: "update", entity: "roles", data: changeset.roles });
|
|
188
|
+
}
|
|
189
|
+
return ops;
|
|
190
|
+
}
|
|
191
|
+
/**
|
|
192
|
+
* Topologically sorts expressions so that parents appear before children,
|
|
193
|
+
* using the `parentId` field. Expressions with `parentId: null` (roots)
|
|
194
|
+
* come first, followed by their children in dependency order.
|
|
195
|
+
*/
|
|
196
|
+
function topologicalSortExpressions(expressions) {
|
|
197
|
+
if (expressions.length <= 1)
|
|
198
|
+
return expressions;
|
|
199
|
+
const byId = new Map();
|
|
200
|
+
for (const expr of expressions) {
|
|
201
|
+
byId.set(expr.id, expr);
|
|
202
|
+
}
|
|
203
|
+
const sorted = [];
|
|
204
|
+
const visited = new Set();
|
|
205
|
+
function visit(expr) {
|
|
206
|
+
if (visited.has(expr.id))
|
|
207
|
+
return;
|
|
208
|
+
// If this expression has a parent that is also in the insertion set,
|
|
209
|
+
// ensure the parent is emitted first.
|
|
210
|
+
if (expr.parentId !== null && byId.has(expr.parentId)) {
|
|
211
|
+
visit(byId.get(expr.parentId));
|
|
212
|
+
}
|
|
213
|
+
visited.add(expr.id);
|
|
214
|
+
sorted.push(expr);
|
|
215
|
+
}
|
|
216
|
+
for (const expr of expressions) {
|
|
217
|
+
visit(expr);
|
|
218
|
+
}
|
|
219
|
+
return sorted;
|
|
220
|
+
}
|
|
221
|
+
//# sourceMappingURL=changeset.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"changeset.js","sourceRoot":"","sources":["../../../src/lib/utils/changeset.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import type { TClaimLookup, TSourceLookup, TClaimSourceLookup } from "../core/interfaces/library.interfaces.js";
|
|
2
|
+
/**
|
|
3
|
+
* Creates a keyed lookup from an array of items. Items are indexed by a
|
|
4
|
+
* composite string key (typically `"id:version"`), and the returned object
|
|
5
|
+
* exposes a `get(id, version)` method that reconstructs the same key
|
|
6
|
+
* internally.
|
|
7
|
+
*
|
|
8
|
+
* Use this to build the `TClaimLookup` or `TSourceLookup` required by
|
|
9
|
+
* `ArgumentEngine`'s constructor from flat arrays (e.g. database query
|
|
10
|
+
* results).
|
|
11
|
+
*
|
|
12
|
+
* @param items - The array of items to index.
|
|
13
|
+
* @param getKey - A function that produces the composite key for each item.
|
|
14
|
+
* Must return a string of the form `"id:version"` so that the returned
|
|
15
|
+
* `get(id, version)` method can reconstruct it.
|
|
16
|
+
* @returns An object with a `get(id, version)` method that looks up items
|
|
17
|
+
* by reconstructing the composite key. Returns `undefined` if no item
|
|
18
|
+
* matches.
|
|
19
|
+
*
|
|
20
|
+
* @example
|
|
21
|
+
* ```ts
|
|
22
|
+
* const claimLookup = createLookup(claims, (c) => `${c.id}:${c.version}`)
|
|
23
|
+
* const sourceLookup = createLookup(sources, (s) => `${s.id}:${s.version}`)
|
|
24
|
+
* const engine = new ArgumentEngine(arg, claimLookup, sourceLookup, ...)
|
|
25
|
+
* ```
|
|
26
|
+
*/
|
|
27
|
+
export declare function createLookup<T>(items: T[], getKey: (item: T) => string): {
|
|
28
|
+
get(id: string, version: number): T | undefined;
|
|
29
|
+
};
|
|
30
|
+
/**
|
|
31
|
+
* A no-op claim lookup that always returns `undefined`. Use this when the
|
|
32
|
+
* consumer does not use claims (e.g. an argument with no claim-bound
|
|
33
|
+
* variables).
|
|
34
|
+
*/
|
|
35
|
+
export declare const EMPTY_CLAIM_LOOKUP: TClaimLookup;
|
|
36
|
+
/**
|
|
37
|
+
* A no-op source lookup that always returns `undefined`. Use this when the
|
|
38
|
+
* consumer does not use sources.
|
|
39
|
+
*/
|
|
40
|
+
export declare const EMPTY_SOURCE_LOOKUP: TSourceLookup;
|
|
41
|
+
/**
|
|
42
|
+
* A no-op claim-source association lookup that always returns `undefined`
|
|
43
|
+
* or empty arrays. Use this when the consumer does not use claim-source
|
|
44
|
+
* associations.
|
|
45
|
+
*/
|
|
46
|
+
export declare const EMPTY_CLAIM_SOURCE_LOOKUP: TClaimSourceLookup;
|
|
47
|
+
//# sourceMappingURL=lookup.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"lookup.d.ts","sourceRoot":"","sources":["../../../src/lib/utils/lookup.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACR,YAAY,EACZ,aAAa,EACb,kBAAkB,EACrB,MAAM,0CAA0C,CAAA;AAEjD;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,wBAAgB,YAAY,CAAC,CAAC,EAC1B,KAAK,EAAE,CAAC,EAAE,EACV,MAAM,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,MAAM,GAC5B;IAAE,GAAG,CAAC,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,CAAC,GAAG,SAAS,CAAA;CAAE,CAUrD;AAED;;;;GAIG;AACH,eAAO,MAAM,kBAAkB,EAAE,YAEhC,CAAA;AAED;;;GAGG;AACH,eAAO,MAAM,mBAAmB,EAAE,aAEjC,CAAA;AAED;;;;GAIG;AACH,eAAO,MAAM,yBAAyB,EAAE,kBAIvC,CAAA"}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Creates a keyed lookup from an array of items. Items are indexed by a
|
|
3
|
+
* composite string key (typically `"id:version"`), and the returned object
|
|
4
|
+
* exposes a `get(id, version)` method that reconstructs the same key
|
|
5
|
+
* internally.
|
|
6
|
+
*
|
|
7
|
+
* Use this to build the `TClaimLookup` or `TSourceLookup` required by
|
|
8
|
+
* `ArgumentEngine`'s constructor from flat arrays (e.g. database query
|
|
9
|
+
* results).
|
|
10
|
+
*
|
|
11
|
+
* @param items - The array of items to index.
|
|
12
|
+
* @param getKey - A function that produces the composite key for each item.
|
|
13
|
+
* Must return a string of the form `"id:version"` so that the returned
|
|
14
|
+
* `get(id, version)` method can reconstruct it.
|
|
15
|
+
* @returns An object with a `get(id, version)` method that looks up items
|
|
16
|
+
* by reconstructing the composite key. Returns `undefined` if no item
|
|
17
|
+
* matches.
|
|
18
|
+
*
|
|
19
|
+
* @example
|
|
20
|
+
* ```ts
|
|
21
|
+
* const claimLookup = createLookup(claims, (c) => `${c.id}:${c.version}`)
|
|
22
|
+
* const sourceLookup = createLookup(sources, (s) => `${s.id}:${s.version}`)
|
|
23
|
+
* const engine = new ArgumentEngine(arg, claimLookup, sourceLookup, ...)
|
|
24
|
+
* ```
|
|
25
|
+
*/
|
|
26
|
+
export function createLookup(items, getKey) {
|
|
27
|
+
const map = new Map();
|
|
28
|
+
for (const item of items) {
|
|
29
|
+
map.set(getKey(item), item);
|
|
30
|
+
}
|
|
31
|
+
return {
|
|
32
|
+
get(id, version) {
|
|
33
|
+
return map.get(`${id}:${version}`);
|
|
34
|
+
},
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* A no-op claim lookup that always returns `undefined`. Use this when the
|
|
39
|
+
* consumer does not use claims (e.g. an argument with no claim-bound
|
|
40
|
+
* variables).
|
|
41
|
+
*/
|
|
42
|
+
export const EMPTY_CLAIM_LOOKUP = {
|
|
43
|
+
get: () => undefined,
|
|
44
|
+
};
|
|
45
|
+
/**
|
|
46
|
+
* A no-op source lookup that always returns `undefined`. Use this when the
|
|
47
|
+
* consumer does not use sources.
|
|
48
|
+
*/
|
|
49
|
+
export const EMPTY_SOURCE_LOOKUP = {
|
|
50
|
+
get: () => undefined,
|
|
51
|
+
};
|
|
52
|
+
/**
|
|
53
|
+
* A no-op claim-source association lookup that always returns `undefined`
|
|
54
|
+
* or empty arrays. Use this when the consumer does not use claim-source
|
|
55
|
+
* associations.
|
|
56
|
+
*/
|
|
57
|
+
export const EMPTY_CLAIM_SOURCE_LOOKUP = {
|
|
58
|
+
getForClaim: () => [],
|
|
59
|
+
getForSource: () => [],
|
|
60
|
+
get: () => undefined,
|
|
61
|
+
};
|
|
62
|
+
//# sourceMappingURL=lookup.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"lookup.js","sourceRoot":"","sources":["../../../src/lib/utils/lookup.ts"],"names":[],"mappings":"AAMA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,MAAM,UAAU,YAAY,CACxB,KAAU,EACV,MAA2B;IAE3B,MAAM,GAAG,GAAG,IAAI,GAAG,EAAa,CAAA;IAChC,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACvB,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,IAAI,CAAC,CAAA;IAC/B,CAAC;IACD,OAAO;QACH,GAAG,CAAC,EAAU,EAAE,OAAe;YAC3B,OAAO,GAAG,CAAC,GAAG,CAAC,GAAG,EAAE,IAAI,OAAO,EAAE,CAAC,CAAA;QACtC,CAAC;KACJ,CAAA;AACL,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAAiB;IAC5C,GAAG,EAAE,GAAG,EAAE,CAAC,SAAS;CACvB,CAAA;AAED;;;GAGG;AACH,MAAM,CAAC,MAAM,mBAAmB,GAAkB;IAC9C,GAAG,EAAE,GAAG,EAAE,CAAC,SAAS;CACvB,CAAA;AAED;;;;GAIG;AACH,MAAM,CAAC,MAAM,yBAAyB,GAAuB;IACzD,WAAW,EAAE,GAAG,EAAE,CAAC,EAAE;IACrB,YAAY,EAAE,GAAG,EAAE,CAAC,EAAE;IACtB,GAAG,EAAE,GAAG,EAAE,CAAC,SAAS;CACvB,CAAA"}
|