@flighthq/requirements 0.3.1-next.616.aa7ae7f

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.
@@ -0,0 +1,3 @@
1
+ export * from './requirementCollector';
2
+ export * from './requirementSet';
3
+ //# sourceMappingURL=contract.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"contract.d.ts","sourceRoot":"","sources":["../src/contract.ts"],"names":[],"mappings":"AAAA,cAAc,wBAAwB,CAAC;AACvC,cAAc,kBAAkB,CAAC"}
@@ -0,0 +1,3 @@
1
+ export * from './requirementCollector';
2
+ export * from './requirementSet';
3
+ //# sourceMappingURL=contract.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"contract.js","sourceRoot":"","sources":["../src/contract.ts"],"names":[],"mappings":"AAAA,cAAc,wBAAwB,CAAC;AACvC,cAAc,kBAAkB,CAAC"}
@@ -0,0 +1,2 @@
1
+ export * from './contract';
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,2 @@
1
+ export * from './contract';
2
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAC"}
@@ -0,0 +1,4 @@
1
+ import type { Kind, Requirement, RequirementFacet, RequirementSet } from '@flighthq/types/contract';
2
+ export declare function collectScene2DRequirements(run: (sink: Requirement[]) => void): RequirementSet;
3
+ export declare function reportRequirement(sink: Requirement[] | undefined, facet: RequirementFacet, key: Kind): void;
4
+ //# sourceMappingURL=requirementCollector.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"requirementCollector.d.ts","sourceRoot":"","sources":["../src/requirementCollector.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,WAAW,EAAE,gBAAgB,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAOpG,wBAAgB,0BAA0B,CAAC,GAAG,EAAE,CAAC,IAAI,EAAE,WAAW,EAAE,KAAK,IAAI,GAAG,cAAc,CAO7F;AAID,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,WAAW,EAAE,GAAG,SAAS,EAAE,KAAK,EAAE,gBAAgB,EAAE,GAAG,EAAE,IAAI,GAAG,IAAI,CAG3G"}
@@ -0,0 +1,17 @@
1
+ import { RequirementFacet as Facet } from '@flighthq/types/contract';
2
+ import { createRequirementSet } from './requirementSet';
3
+ // Engages requirement recording for one Scene2D import. Parsers receive the same optional-array sink
4
+ // shape as import diagnostics; an unengaged parse receives `undefined` and allocates no requirement.
5
+ export function collectScene2DRequirements(run) {
6
+ const requirements = [];
7
+ run(requirements);
8
+ return createRequirementSet([Facet.SceneBlendMode, Facet.SceneMaterialKind, Facet.SceneNodeKind, Facet.SceneShapeCommand], requirements);
9
+ }
10
+ // The colocated importer seam. Call it only where a parser has established the content fact; when no
11
+ // collector is engaged the default parse pays one undefined check and records nothing.
12
+ export function reportRequirement(sink, facet, key) {
13
+ if (sink === undefined)
14
+ return;
15
+ sink.push({ facet, key });
16
+ }
17
+ //# sourceMappingURL=requirementCollector.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"requirementCollector.js","sourceRoot":"","sources":["../src/requirementCollector.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,gBAAgB,IAAI,KAAK,EAAE,MAAM,0BAA0B,CAAC;AAErE,OAAO,EAAE,oBAAoB,EAAE,MAAM,kBAAkB,CAAC;AAExD,qGAAqG;AACrG,qGAAqG;AACrG,MAAM,UAAU,0BAA0B,CAAC,GAAkC;IAC3E,MAAM,YAAY,GAAkB,EAAE,CAAC;IACvC,GAAG,CAAC,YAAY,CAAC,CAAC;IAClB,OAAO,oBAAoB,CACzB,CAAC,KAAK,CAAC,cAAc,EAAE,KAAK,CAAC,iBAAiB,EAAE,KAAK,CAAC,aAAa,EAAE,KAAK,CAAC,iBAAiB,CAAC,EAC7F,YAAY,CACb,CAAC;AACJ,CAAC;AAED,qGAAqG;AACrG,uFAAuF;AACvF,MAAM,UAAU,iBAAiB,CAAC,IAA+B,EAAE,KAAuB,EAAE,GAAS;IACnG,IAAI,IAAI,KAAK,SAAS;QAAE,OAAO;IAC/B,IAAI,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,GAAG,EAAE,CAAC,CAAC;AAC5B,CAAC"}
@@ -0,0 +1,5 @@
1
+ import type { Requirement, RequirementFacet, RequirementSet } from '@flighthq/types/contract';
2
+ export declare function createRequirementSet(covers: readonly RequirementFacet[], requirements: readonly Readonly<Requirement>[]): RequirementSet;
3
+ export declare function diffRequirementSets(requirements: Readonly<RequirementSet>, baseline: Readonly<RequirementSet>): RequirementSet;
4
+ export declare function mergeRequirementSets(requirementSets: readonly Readonly<RequirementSet>[]): RequirementSet;
5
+ //# sourceMappingURL=requirementSet.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"requirementSet.d.ts","sourceRoot":"","sources":["../src/requirementSet.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,gBAAgB,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAE9F,wBAAgB,oBAAoB,CAClC,MAAM,EAAE,SAAS,gBAAgB,EAAE,EACnC,YAAY,EAAE,SAAS,QAAQ,CAAC,WAAW,CAAC,EAAE,GAC7C,cAAc,CAKhB;AAID,wBAAgB,mBAAmB,CACjC,YAAY,EAAE,QAAQ,CAAC,cAAc,CAAC,EACtC,QAAQ,EAAE,QAAQ,CAAC,cAAc,CAAC,GACjC,cAAc,CAahB;AAID,wBAAgB,oBAAoB,CAAC,eAAe,EAAE,SAAS,QAAQ,CAAC,cAAc,CAAC,EAAE,GAAG,cAAc,CASzG"}
@@ -0,0 +1,48 @@
1
+ export function createRequirementSet(covers, requirements) {
2
+ return {
3
+ covers: distinctSorted(covers),
4
+ requirements: distinctSortedRequirements(requirements),
5
+ };
6
+ }
7
+ // A difference can claim completeness only where both operands inspected the facet. Requirements from
8
+ // an unshared facet are therefore unknown, not absent, and do not enter the result.
9
+ export function diffRequirementSets(requirements, baseline) {
10
+ const covers = intersectSorted(requirements.covers, baseline.covers);
11
+ const baselineKeys = new Set(baseline.requirements.map((requirement) => requirementIdentity(requirement.facet, requirement.key)));
12
+ return createRequirementSet(covers, requirements.requirements.filter((requirement) => covers.includes(requirement.facet) &&
13
+ !baselineKeys.has(requirementIdentity(requirement.facet, requirement.key))));
14
+ }
15
+ // A merged set is complete for a facet only when every input inspected it. Requirements themselves are
16
+ // unioned, because a partial producer can still contribute a positive fact without proving negatives.
17
+ export function mergeRequirementSets(requirementSets) {
18
+ if (requirementSets.length === 0)
19
+ return createRequirementSet([], []);
20
+ let covers = distinctSorted(requirementSets[0].covers);
21
+ const requirements = [];
22
+ for (const requirementSet of requirementSets) {
23
+ covers = intersectSorted(covers, requirementSet.covers);
24
+ requirements.push(...requirementSet.requirements);
25
+ }
26
+ return createRequirementSet(covers, requirements);
27
+ }
28
+ function distinctSorted(values) {
29
+ return [...new Set(values)].sort();
30
+ }
31
+ function distinctSortedRequirements(requirements) {
32
+ const byIdentity = new Map();
33
+ for (const requirement of requirements) {
34
+ byIdentity.set(requirementIdentity(requirement.facet, requirement.key), {
35
+ facet: requirement.facet,
36
+ key: requirement.key,
37
+ });
38
+ }
39
+ return [...byIdentity.values()].sort((a, b) => a.facet.localeCompare(b.facet) || a.key.localeCompare(b.key));
40
+ }
41
+ function intersectSorted(first, second) {
42
+ const secondValues = new Set(second);
43
+ return distinctSorted(first.filter((value) => secondValues.has(value)));
44
+ }
45
+ function requirementIdentity(facet, key) {
46
+ return `${facet}\0${key}`;
47
+ }
48
+ //# sourceMappingURL=requirementSet.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"requirementSet.js","sourceRoot":"","sources":["../src/requirementSet.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,48 @@
1
+ {
2
+ "name": "@flighthq/requirements",
3
+ "version": "0.3.1-next.616.aa7ae7f",
4
+ "author": "Joshua Granick and other contributors",
5
+ "license": "MIT",
6
+ "repository": {
7
+ "type": "git",
8
+ "url": "https://github.com/flighthq/flight.git",
9
+ "directory": "packages/requirements"
10
+ },
11
+ "type": "module",
12
+ "main": "dist/index.js",
13
+ "types": "dist/index.d.ts",
14
+ "exports": {
15
+ ".": {
16
+ "types": "./dist/index.d.ts",
17
+ "default": "./dist/index.js"
18
+ },
19
+ "./contract": {
20
+ "types": "./dist/contract.d.ts",
21
+ "default": "./dist/contract.js"
22
+ }
23
+ },
24
+ "files": [
25
+ "dist",
26
+ "src/**/*.test.ts",
27
+ "!dist/**/*.test.js",
28
+ "!dist/**/*.test.d.ts",
29
+ "!dist/**/*.test.js.map",
30
+ "!dist/**/*.test.d.ts.map"
31
+ ],
32
+ "scripts": {
33
+ "build": "tsc -b",
34
+ "clean": "tsc -b --clean",
35
+ "test": "vitest run --config vitest.config.ts",
36
+ "test:watch": "vitest --watch --config vitest.config.ts",
37
+ "prepack": "npm run clean && npm run clean:dist && npm run build",
38
+ "clean:dist": "tsx ../../scripts/clean-package-dist.ts"
39
+ },
40
+ "dependencies": {
41
+ "@flighthq/types": "0.3.1-next.616.aa7ae7f"
42
+ },
43
+ "devDependencies": {
44
+ "typescript": "^5.3.0"
45
+ },
46
+ "description": "Plain requirement collection and set algebra for content-to-registration resolution",
47
+ "sideEffects": false
48
+ }
@@ -0,0 +1,36 @@
1
+ import type { Requirement } from '@flighthq/types/contract';
2
+ import { RequirementFacet } from '@flighthq/types/contract';
3
+
4
+ import { collectScene2DRequirements, reportRequirement } from './requirementCollector';
5
+
6
+ describe('collectScene2DRequirements', () => {
7
+ it('returns deterministic distinct requirements and the facets inspected by the collector', () => {
8
+ const result = collectScene2DRequirements((sink) => {
9
+ reportRequirement(sink, RequirementFacet.SceneNodeKind, 'Shape');
10
+ reportRequirement(sink, RequirementFacet.SceneBlendMode, 'Multiply');
11
+ reportRequirement(sink, RequirementFacet.SceneNodeKind, 'Shape');
12
+ });
13
+
14
+ expect(result).toEqual({
15
+ covers: [
16
+ RequirementFacet.SceneBlendMode,
17
+ RequirementFacet.SceneMaterialKind,
18
+ RequirementFacet.SceneNodeKind,
19
+ RequirementFacet.SceneShapeCommand,
20
+ ],
21
+ requirements: [
22
+ { facet: RequirementFacet.SceneBlendMode, key: 'Multiply' },
23
+ { facet: RequirementFacet.SceneNodeKind, key: 'Shape' },
24
+ ],
25
+ });
26
+ });
27
+ });
28
+
29
+ describe('reportRequirement', () => {
30
+ it('records only when a collector is engaged', () => {
31
+ const sink: Requirement[] = [];
32
+ reportRequirement(undefined, RequirementFacet.SceneNodeKind, 'Shape');
33
+ reportRequirement(sink, RequirementFacet.SceneNodeKind, 'Shape');
34
+ expect(sink).toEqual([{ facet: RequirementFacet.SceneNodeKind, key: 'Shape' }]);
35
+ });
36
+ });
@@ -0,0 +1,71 @@
1
+ import { RequirementFacet } from '@flighthq/types/contract';
2
+
3
+ import { createRequirementSet, diffRequirementSets, mergeRequirementSets } from './requirementSet';
4
+
5
+ describe('createRequirementSet', () => {
6
+ it('copies, sorts, and deduplicates both dimensions', () => {
7
+ const covers = [RequirementFacet.SceneNodeKind, RequirementFacet.SceneBlendMode];
8
+ const requirements = [
9
+ { facet: RequirementFacet.SceneNodeKind, key: 'Shape' },
10
+ { facet: RequirementFacet.SceneBlendMode, key: 'Multiply' },
11
+ { facet: RequirementFacet.SceneNodeKind, key: 'Shape' },
12
+ ];
13
+ const result = createRequirementSet(covers, requirements);
14
+ covers.length = 0;
15
+ requirements.length = 0;
16
+
17
+ expect(result).toEqual({
18
+ covers: [RequirementFacet.SceneBlendMode, RequirementFacet.SceneNodeKind],
19
+ requirements: [
20
+ { facet: RequirementFacet.SceneBlendMode, key: 'Multiply' },
21
+ { facet: RequirementFacet.SceneNodeKind, key: 'Shape' },
22
+ ],
23
+ });
24
+ });
25
+ });
26
+
27
+ describe('diffRequirementSets', () => {
28
+ it('subtracts facts only for facets both operands cover', () => {
29
+ const result = diffRequirementSets(
30
+ createRequirementSet(
31
+ [RequirementFacet.SceneBlendMode, RequirementFacet.SceneNodeKind],
32
+ [
33
+ { facet: RequirementFacet.SceneBlendMode, key: 'Multiply' },
34
+ { facet: RequirementFacet.SceneNodeKind, key: 'Shape' },
35
+ ],
36
+ ),
37
+ createRequirementSet(
38
+ [RequirementFacet.SceneNodeKind],
39
+ [{ facet: RequirementFacet.SceneNodeKind, key: 'Sprite' }],
40
+ ),
41
+ );
42
+
43
+ expect(result).toEqual({
44
+ covers: [RequirementFacet.SceneNodeKind],
45
+ requirements: [{ facet: RequirementFacet.SceneNodeKind, key: 'Shape' }],
46
+ });
47
+ });
48
+ });
49
+
50
+ describe('mergeRequirementSets', () => {
51
+ it('unions facts while intersecting completeness', () => {
52
+ const result = mergeRequirementSets([
53
+ createRequirementSet(
54
+ [RequirementFacet.SceneBlendMode, RequirementFacet.SceneNodeKind],
55
+ [{ facet: RequirementFacet.SceneNodeKind, key: 'Shape' }],
56
+ ),
57
+ createRequirementSet(
58
+ [RequirementFacet.SceneNodeKind],
59
+ [{ facet: RequirementFacet.SceneNodeKind, key: 'Sprite' }],
60
+ ),
61
+ ]);
62
+
63
+ expect(result).toEqual({
64
+ covers: [RequirementFacet.SceneNodeKind],
65
+ requirements: [
66
+ { facet: RequirementFacet.SceneNodeKind, key: 'Shape' },
67
+ { facet: RequirementFacet.SceneNodeKind, key: 'Sprite' },
68
+ ],
69
+ });
70
+ });
71
+ });