obix-spec 0.2.1

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 ADDED
@@ -0,0 +1,47 @@
1
+ # obix-spec
2
+
3
+ **Canonical types + structural contracts for OBIX 1.0. Zero runtime dependencies.**
4
+
5
+ ```bash
6
+ npm install obix-spec
7
+ ```
8
+
9
+ ## Purpose
10
+
11
+ `obix-spec` is the single source of truth for every OBIX interface. Nothing else
12
+ in the family redefines `DOPArtifact`, `ActionSignature`, `BindingDescriptor`,
13
+ `EffectDescriptor`, `A11yModel`, `TransitionMeta`, `ValidationResult`, … — they
14
+ import from here. This is the fix for *Problem 12 — TypeScript declaration drift*:
15
+ the types are plain TypeScript source, `.d.ts` is emitted from it, and there is no
16
+ separate IDL generator.
17
+
18
+ ## Dependency role
19
+
20
+ Bottom of the graph. Depends on **nothing**. Imported (types-only, mostly) by
21
+ all 19 other packages.
22
+
23
+ ## Level 0 status
24
+
25
+ ✅ Complete. The type surface covers the full Level 0 pipeline; a few fields
26
+ (`DOPArtifact.template`, `.style`, `.a11y`) are optional and only populated once
27
+ the compiler runs.
28
+
29
+ ## Public API
30
+
31
+ | Export | Kind | Notes |
32
+ |---|---|---|
33
+ | `SPEC_VERSION` | `"0.2.1"` | the frozen language revision |
34
+ | `LEVEL` | `0` | implementation milestone |
35
+ | `createScopeToken(name, sourcePath?)` | fn | the **one** scope-token function (Problem 10) |
36
+ | `SCOPE_ATTR` | `"data-obix-scope"` | attribute the token is applied through |
37
+ | `validateObixAST(ast)` | fn | the parser seal (Problem 7) — structural, not cryptographic |
38
+ | `validateArtifactShape(artifact)` | fn | runtime shape check for a `DOPArtifact` |
39
+ | `UnsupportedFeatureError` | class | `{ feature, requiredLevel, currentLevel }` |
40
+ | `DIAGNOSTIC_CODES` | frozen map | stable `OBIX-<area><nnn>` codes |
41
+ | *types* | — | `DOPArtifact`, `ActionFn`, `DerivedFn`, `ActionSignature`, `DerivedSignature`, `TemplateDescriptor`, `TemplateNode`, `BindingDescriptor`, `EventDescriptor`, `EffectDescriptor`, `A11yModel`, `TransitionMeta`, `ActionTrace`, `SourceSpan`, `Diagnostic`, `ValidationResult`, `ValidationDescriptor`, `DopIR`, `EmitMode`, … |
42
+
43
+ ## Relationship to DOP IR
44
+
45
+ `obix-spec` defines the **shape** of the canonical DOP IR (`DopIR`) and of the
46
+ runnable `DOPArtifact`. It contains no logic that builds or projects them — that
47
+ is `obix-ir` and the adapters. Data first: the types describe data, not paradigm.
@@ -0,0 +1,33 @@
1
+ export declare const DIAGNOSTIC_CODES: Readonly<{
2
+ C011_VERSION_MISMATCH: "OBIX-C011";
3
+ P001_MISSING_TEMPLATE: "OBIX-P001";
4
+ P002_MISSING_SCRIPT: "OBIX-P002";
5
+ P003_DUPLICATE_SECTION: "OBIX-P003";
6
+ P004_UNCLOSED_TAG: "OBIX-P004";
7
+ P005_UNEXPECTED_TOKEN: "OBIX-P005";
8
+ P006_BAD_INTERPOLATION: "OBIX-P006";
9
+ P007_UNKNOWN_DIRECTIVE: "OBIX-P007";
10
+ P008_BAD_COMPONENT_NAME: "OBIX-P008";
11
+ S001_UNKNOWN_ACTION: "OBIX-S001";
12
+ S002_UNKNOWN_BINDING_REF: "OBIX-S002";
13
+ S003_ACTION_ARITY: "OBIX-S003";
14
+ S004_PROP_DEP_UNDECLARED: "OBIX-S004";
15
+ S005_PIPELINE_INVARIANT: "OBIX-S005";
16
+ S006_STATE_SHAPE_NOT_CLOSED: "OBIX-S006";
17
+ A001_LIVE_REGION_INVALID: "OBIX-A001";
18
+ A002_LIVE_REGION_NO_BINDING: "OBIX-A002";
19
+ A003_FOCUS_POLICY: "OBIX-A003";
20
+ A004_HEADING_SKIP: "OBIX-A004";
21
+ A005_UNKNOWN_ROLE: "OBIX-A005";
22
+ A006_UNKNOWN_ARIA_ATTR: "OBIX-A006";
23
+ E001_UNSUPPORTED_EMIT_MODE: "OBIX-E001";
24
+ X001_ADAPTER_DIVERGENCE: "OBIX-X001";
25
+ }>;
26
+ export type DiagnosticCode = (typeof DIAGNOSTIC_CODES)[keyof typeof DIAGNOSTIC_CODES];
27
+ export declare class UnsupportedFeatureError extends Error {
28
+ readonly feature: string;
29
+ readonly requiredLevel: number;
30
+ readonly currentLevel: number;
31
+ constructor(feature: string, requiredLevel: number, currentLevel?: number);
32
+ }
33
+ //# sourceMappingURL=diagnostics.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"diagnostics.d.ts","sourceRoot":"","sources":["../src/diagnostics.ts"],"names":[],"mappings":"AAOA,eAAO,MAAM,gBAAgB;;;;;;;;;;;;;;;;;;;;;;;;EA8B3B,CAAC;AAEH,MAAM,MAAM,cAAc,GAAG,CAAC,OAAO,gBAAgB,CAAC,CAAC,MAAM,OAAO,gBAAgB,CAAC,CAAC;AAOtF,qBAAa,uBAAwB,SAAQ,KAAK;IAChD,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;gBAElB,OAAO,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,EAAE,YAAY,GAAE,MAAc;CASjF"}
@@ -0,0 +1,39 @@
1
+ import { LEVEL } from "./version.js";
2
+ export const DIAGNOSTIC_CODES = Object.freeze({
3
+ C011_VERSION_MISMATCH: "OBIX-C011",
4
+ P001_MISSING_TEMPLATE: "OBIX-P001",
5
+ P002_MISSING_SCRIPT: "OBIX-P002",
6
+ P003_DUPLICATE_SECTION: "OBIX-P003",
7
+ P004_UNCLOSED_TAG: "OBIX-P004",
8
+ P005_UNEXPECTED_TOKEN: "OBIX-P005",
9
+ P006_BAD_INTERPOLATION: "OBIX-P006",
10
+ P007_UNKNOWN_DIRECTIVE: "OBIX-P007",
11
+ P008_BAD_COMPONENT_NAME: "OBIX-P008",
12
+ S001_UNKNOWN_ACTION: "OBIX-S001",
13
+ S002_UNKNOWN_BINDING_REF: "OBIX-S002",
14
+ S003_ACTION_ARITY: "OBIX-S003",
15
+ S004_PROP_DEP_UNDECLARED: "OBIX-S004",
16
+ S005_PIPELINE_INVARIANT: "OBIX-S005",
17
+ S006_STATE_SHAPE_NOT_CLOSED: "OBIX-S006",
18
+ A001_LIVE_REGION_INVALID: "OBIX-A001",
19
+ A002_LIVE_REGION_NO_BINDING: "OBIX-A002",
20
+ A003_FOCUS_POLICY: "OBIX-A003",
21
+ A004_HEADING_SKIP: "OBIX-A004",
22
+ A005_UNKNOWN_ROLE: "OBIX-A005",
23
+ A006_UNKNOWN_ARIA_ATTR: "OBIX-A006",
24
+ E001_UNSUPPORTED_EMIT_MODE: "OBIX-E001",
25
+ X001_ADAPTER_DIVERGENCE: "OBIX-X001",
26
+ });
27
+ export class UnsupportedFeatureError extends Error {
28
+ feature;
29
+ requiredLevel;
30
+ currentLevel;
31
+ constructor(feature, requiredLevel, currentLevel = LEVEL) {
32
+ super(`[OBIX] "${feature}" requires Level ${requiredLevel}; this build implements Level ${currentLevel}.`);
33
+ this.name = "UnsupportedFeatureError";
34
+ this.feature = feature;
35
+ this.requiredLevel = requiredLevel;
36
+ this.currentLevel = currentLevel;
37
+ }
38
+ }
39
+ //# sourceMappingURL=diagnostics.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"diagnostics.js","sourceRoot":"","sources":["../src/diagnostics.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,cAAc,CAAC;AAOrC,MAAM,CAAC,MAAM,gBAAgB,GAAG,MAAM,CAAC,MAAM,CAAC;IAE5C,qBAAqB,EAAE,WAAW;IAElC,qBAAqB,EAAE,WAAW;IAClC,mBAAmB,EAAE,WAAW;IAChC,sBAAsB,EAAE,WAAW;IACnC,iBAAiB,EAAE,WAAW;IAC9B,qBAAqB,EAAE,WAAW;IAClC,sBAAsB,EAAE,WAAW;IACnC,sBAAsB,EAAE,WAAW;IACnC,uBAAuB,EAAE,WAAW;IAEpC,mBAAmB,EAAE,WAAW;IAChC,wBAAwB,EAAE,WAAW;IACrC,iBAAiB,EAAE,WAAW;IAC9B,wBAAwB,EAAE,WAAW;IACrC,uBAAuB,EAAE,WAAW;IACpC,2BAA2B,EAAE,WAAW;IAExC,wBAAwB,EAAE,WAAW;IACrC,2BAA2B,EAAE,WAAW;IACxC,iBAAiB,EAAE,WAAW;IAC9B,iBAAiB,EAAE,WAAW;IAC9B,iBAAiB,EAAE,WAAW;IAC9B,sBAAsB,EAAE,WAAW;IAEnC,0BAA0B,EAAE,WAAW;IAEvC,uBAAuB,EAAE,WAAW;CACrC,CAAC,CAAC;AASH,MAAM,OAAO,uBAAwB,SAAQ,KAAK;IACvC,OAAO,CAAS;IAChB,aAAa,CAAS;IACtB,YAAY,CAAS;IAE9B,YAAY,OAAe,EAAE,aAAqB,EAAE,eAAuB,KAAK;QAC9E,KAAK,CACH,WAAW,OAAO,oBAAoB,aAAa,iCAAiC,YAAY,GAAG,CACpG,CAAC;QACF,IAAI,CAAC,IAAI,GAAG,yBAAyB,CAAC;QACtC,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;QACvB,IAAI,CAAC,aAAa,GAAG,aAAa,CAAC;QACnC,IAAI,CAAC,YAAY,GAAG,YAAY,CAAC;IACnC,CAAC;CACF"}
@@ -0,0 +1,9 @@
1
+ export * from "./types.js";
2
+ export { SPEC_VERSION, LEVEL } from "./version.js";
3
+ export type { ObixLevel } from "./version.js";
4
+ export { DIAGNOSTIC_CODES, UnsupportedFeatureError } from "./diagnostics.js";
5
+ export type { DiagnosticCode } from "./diagnostics.js";
6
+ export { createScopeToken, SCOPE_ATTR } from "./scope-token.js";
7
+ export { validateObixAST } from "./validate-ast.js";
8
+ export { validateArtifactShape } from "./validate-artifact.js";
9
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAOA,cAAc,YAAY,CAAC;AAC3B,OAAO,EAAE,YAAY,EAAE,KAAK,EAAE,MAAM,cAAc,CAAC;AACnD,YAAY,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAC9C,OAAO,EAAE,gBAAgB,EAAE,uBAAuB,EAAE,MAAM,kBAAkB,CAAC;AAC7E,YAAY,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AACvD,OAAO,EAAE,gBAAgB,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAChE,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACpD,OAAO,EAAE,qBAAqB,EAAE,MAAM,wBAAwB,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,7 @@
1
+ export * from "./types.js";
2
+ export { SPEC_VERSION, LEVEL } from "./version.js";
3
+ export { DIAGNOSTIC_CODES, UnsupportedFeatureError } from "./diagnostics.js";
4
+ export { createScopeToken, SCOPE_ATTR } from "./scope-token.js";
5
+ export { validateObixAST } from "./validate-ast.js";
6
+ export { validateArtifactShape } from "./validate-artifact.js";
7
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAOA,cAAc,YAAY,CAAC;AAC3B,OAAO,EAAE,YAAY,EAAE,KAAK,EAAE,MAAM,cAAc,CAAC;AAEnD,OAAO,EAAE,gBAAgB,EAAE,uBAAuB,EAAE,MAAM,kBAAkB,CAAC;AAE7E,OAAO,EAAE,gBAAgB,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAChE,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACpD,OAAO,EAAE,qBAAqB,EAAE,MAAM,wBAAwB,CAAC"}
@@ -0,0 +1,3 @@
1
+ export declare function createScopeToken(componentName: string, sourcePath?: string): string;
2
+ export declare const SCOPE_ATTR: "data-obix-scope";
3
+ //# sourceMappingURL=scope-token.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scope-token.d.ts","sourceRoot":"","sources":["../src/scope-token.ts"],"names":[],"mappings":"AAOA,wBAAgB,gBAAgB,CAAC,aAAa,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,MAAM,GAAG,MAAM,CAQnF;AAGD,eAAO,MAAM,UAAU,EAAG,iBAA0B,CAAC"}
Binary file
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scope-token.js","sourceRoot":"","sources":["../src/scope-token.ts"],"names":[],"mappings":"AAOA,MAAM,UAAU,gBAAgB,CAAC,aAAqB,EAAE,UAAmB;IACzE,MAAM,KAAK,GAAG,GAAG,aAAa,IAAI,UAAU,IAAI,EAAE,EAAE,CAAC;IACrD,IAAI,CAAC,GAAG,UAAU,CAAC;IACnB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACtC,CAAC,IAAI,KAAK,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;QACzB,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,EAAE,UAAU,CAAC,KAAK,CAAC,CAAC;IACrC,CAAC;IACD,OAAO,QAAQ,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,CAAC;AACnD,CAAC;AAGD,MAAM,CAAC,MAAM,UAAU,GAAG,iBAA0B,CAAC"}
@@ -0,0 +1,195 @@
1
+ export interface SourceSpan {
2
+ readonly start: number;
3
+ readonly end: number;
4
+ readonly line: number;
5
+ readonly column: number;
6
+ }
7
+ export type DiagnosticSeverity = "error" | "warning" | "info";
8
+ export interface Diagnostic {
9
+ readonly code: string;
10
+ readonly severity: DiagnosticSeverity;
11
+ readonly message: string;
12
+ readonly span?: SourceSpan;
13
+ }
14
+ export type StateValue = unknown;
15
+ export type State = Readonly<Record<string, StateValue>>;
16
+ export type Props = Readonly<Record<string, unknown>>;
17
+ export type Payload = unknown;
18
+ export type ActionFn<S extends object = State, P extends object = Props> = (state: S, payload: Payload, props: P) => S;
19
+ export type DerivedFn<S extends object = State, P extends object = Props> = (state: S, props: P) => unknown;
20
+ export interface ActionSignature {
21
+ readonly name: string;
22
+ readonly arity: 1 | 2 | 3;
23
+ readonly usesProps: boolean;
24
+ readonly propDeps: readonly string[];
25
+ }
26
+ export interface DerivedSignature {
27
+ readonly name: string;
28
+ readonly propDeps: readonly string[];
29
+ readonly stateDeps: readonly string[];
30
+ }
31
+ export type EffectKind = "every" | "after" | "on";
32
+ export interface EffectDescriptor {
33
+ readonly name: string;
34
+ readonly kind: EffectKind;
35
+ readonly dispatch: string;
36
+ readonly every?: number;
37
+ readonly whileExpr?: string;
38
+ }
39
+ export type TemplateNode = TemplateElement | TemplateText | TemplateInterpolation;
40
+ export interface TemplateAttr {
41
+ readonly name: string;
42
+ readonly value: string | null;
43
+ readonly interpolation?: string;
44
+ readonly directive?: "event" | "aria" | "bool" | "conditional";
45
+ readonly span?: SourceSpan;
46
+ }
47
+ export interface TemplateElement {
48
+ readonly kind: "element";
49
+ readonly tag: string;
50
+ readonly attrs: readonly TemplateAttr[];
51
+ readonly children: readonly TemplateNode[];
52
+ readonly span?: SourceSpan;
53
+ }
54
+ export interface TemplateText {
55
+ readonly kind: "text";
56
+ readonly value: string;
57
+ readonly span?: SourceSpan;
58
+ }
59
+ export interface TemplateInterpolation {
60
+ readonly kind: "interpolation";
61
+ readonly expr: string;
62
+ readonly span?: SourceSpan;
63
+ }
64
+ export type BindingKind = "text" | "attr" | "bool" | "aria" | "conditional";
65
+ export interface BindingDescriptor {
66
+ readonly kind: BindingKind;
67
+ readonly target: string;
68
+ readonly expr: string;
69
+ readonly deps: readonly string[];
70
+ readonly path: readonly number[];
71
+ }
72
+ export interface EventDescriptor {
73
+ readonly event: string;
74
+ readonly action: string;
75
+ readonly path: readonly number[];
76
+ }
77
+ export interface TemplateDescriptor {
78
+ readonly root: TemplateElement;
79
+ readonly bindings: readonly BindingDescriptor[];
80
+ readonly events: readonly EventDescriptor[];
81
+ }
82
+ export interface A11yLiveRegion {
83
+ readonly path: readonly number[];
84
+ readonly politeness: "polite" | "assertive" | "off";
85
+ readonly hasBinding: boolean;
86
+ }
87
+ export interface A11yModel {
88
+ readonly liveRegions: readonly A11yLiveRegion[];
89
+ readonly focusableCount: number;
90
+ readonly headingLevels: readonly number[];
91
+ readonly roles: readonly string[];
92
+ readonly violations: readonly Diagnostic[];
93
+ }
94
+ export interface Violation {
95
+ readonly rule: string;
96
+ readonly message: string;
97
+ readonly path?: string;
98
+ }
99
+ export interface ValidationResult {
100
+ readonly valid: boolean;
101
+ readonly violations: readonly Violation[];
102
+ }
103
+ export interface ValidationRule<S extends object = State, P extends object = Props> {
104
+ readonly when: (state: S, props: P) => boolean;
105
+ readonly message: string;
106
+ }
107
+ export interface ValidationDescriptor {
108
+ readonly state?: Readonly<Record<string, {
109
+ type?: string;
110
+ min?: number;
111
+ max?: number;
112
+ }>>;
113
+ readonly props?: Readonly<Record<string, {
114
+ type?: string;
115
+ }>>;
116
+ readonly rules?: Readonly<Record<string, ValidationRule>>;
117
+ }
118
+ export interface TransitionMeta<S extends object = State> {
119
+ readonly action: string;
120
+ readonly payload: Payload;
121
+ readonly changedKeys: readonly string[];
122
+ readonly from: S;
123
+ readonly to: S;
124
+ }
125
+ export type TraceItem = readonly [action: string, payload?: Payload];
126
+ export type ActionTrace = readonly TraceItem[];
127
+ export interface DopArtifactMeta {
128
+ readonly specVersion: string;
129
+ readonly level: number;
130
+ readonly actionDecls: Readonly<Record<string, ActionSignature>>;
131
+ readonly derivedDeps: Readonly<Record<string, DerivedSignature>>;
132
+ }
133
+ export interface DOPArtifact<S extends object = State, P extends object = Props> {
134
+ readonly name: string;
135
+ readonly initialState: S;
136
+ readonly props: P;
137
+ readonly actions: Readonly<Record<string, ActionFn<S, P>>>;
138
+ readonly derived: Readonly<Record<string, DerivedFn<S, P>>>;
139
+ readonly effects: Readonly<Record<string, EffectDescriptor>>;
140
+ readonly validate?: (state: S, props: P) => ValidationResult;
141
+ readonly render?: (state: S, props: P) => string;
142
+ readonly template?: TemplateDescriptor;
143
+ readonly style?: {
144
+ readonly token: string;
145
+ readonly css: string;
146
+ };
147
+ readonly a11y?: A11yModel;
148
+ readonly meta: DopArtifactMeta;
149
+ }
150
+ export interface ObixSection {
151
+ readonly raw: string;
152
+ readonly span: SourceSpan;
153
+ }
154
+ export interface ObixScriptModel {
155
+ readonly raw: string;
156
+ readonly stateInit?: string;
157
+ readonly propsInit?: string;
158
+ readonly actionNames: readonly string[];
159
+ readonly derivedNames: readonly string[];
160
+ readonly effectNames: readonly string[];
161
+ readonly members: {
162
+ readonly actions: Readonly<Record<string, string>>;
163
+ readonly derived: Readonly<Record<string, string>>;
164
+ readonly effects: Readonly<Record<string, string>>;
165
+ };
166
+ }
167
+ export interface ObixAST {
168
+ readonly componentName: string;
169
+ readonly sections: {
170
+ readonly style?: ObixSection;
171
+ readonly template?: ObixSection;
172
+ readonly script?: ObixSection;
173
+ };
174
+ readonly template?: TemplateElement;
175
+ readonly script?: ObixScriptModel;
176
+ }
177
+ export interface DopIR {
178
+ readonly name: string;
179
+ readonly specVersion: string;
180
+ readonly level: number;
181
+ readonly stateShape: readonly string[];
182
+ readonly propsShape: readonly string[];
183
+ readonly actionDecls: Readonly<Record<string, ActionSignature>>;
184
+ readonly derivedDeps: Readonly<Record<string, DerivedSignature>>;
185
+ readonly template: TemplateDescriptor;
186
+ readonly events: readonly EventDescriptor[];
187
+ readonly style: {
188
+ readonly token: string;
189
+ readonly css: string;
190
+ };
191
+ readonly a11y: A11yModel;
192
+ readonly effects: Readonly<Record<string, EffectDescriptor>>;
193
+ }
194
+ export type EmitMode = "linked" | "bare" | "inline" | "shared-inline";
195
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
package/dist/types.js ADDED
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":""}
@@ -0,0 +1,3 @@
1
+ import type { ValidationResult } from "./types.js";
2
+ export declare function validateArtifactShape(artifact: unknown): ValidationResult;
3
+ //# sourceMappingURL=validate-artifact.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validate-artifact.d.ts","sourceRoot":"","sources":["../src/validate-artifact.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAa,MAAM,YAAY,CAAC;AAM9D,wBAAgB,qBAAqB,CAAC,QAAQ,EAAE,OAAO,GAAG,gBAAgB,CAqCzE"}
@@ -0,0 +1,43 @@
1
+ export function validateArtifactShape(artifact) {
2
+ const v = [];
3
+ const add = (rule, message, path) => v.push({ rule, message, path });
4
+ if (typeof artifact !== "object" || artifact === null) {
5
+ return { valid: false, violations: [{ rule: "artifact.object", message: "artifact must be an object" }] };
6
+ }
7
+ const a = artifact;
8
+ if (typeof a.name !== "string" || a.name.length === 0)
9
+ add("artifact.name", "name must be a non-empty string", "name");
10
+ if (typeof a.initialState !== "object" || a.initialState === null)
11
+ add("artifact.initialState", "initialState must be an object", "initialState");
12
+ if (typeof a.props !== "object" || a.props === null)
13
+ add("artifact.props", "props must be an object", "props");
14
+ const actions = a.actions;
15
+ if (typeof actions !== "object" || actions === null) {
16
+ add("artifact.actions", "actions must be an object", "actions");
17
+ }
18
+ else {
19
+ for (const [name, fn] of Object.entries(actions)) {
20
+ if (typeof fn !== "function")
21
+ add("artifact.actions.fn", `action "${name}" must be a function`, `actions.${name}`);
22
+ else if (fn.length > 3)
23
+ add("artifact.actions.arity", `action "${name}" has arity ${fn.length}; max is 3 — Action(state, payload, props)`, `actions.${name}`);
24
+ }
25
+ }
26
+ const derived = (a.derived ?? {});
27
+ for (const [name, fn] of Object.entries(derived)) {
28
+ if (typeof fn !== "function")
29
+ add("artifact.derived.fn", `derived "${name}" must be a function`, `derived.${name}`);
30
+ else if (fn.length > 2)
31
+ add("artifact.derived.arity", `derived "${name}" has arity ${fn.length}; max is 2 — Derived(state, props)`, `derived.${name}`);
32
+ }
33
+ const effects = (a.effects ?? {});
34
+ for (const [name, desc] of Object.entries(effects)) {
35
+ const d = desc;
36
+ if (typeof d?.kind !== "string")
37
+ add("artifact.effects.kind", `effect "${name}" needs a kind`, `effects.${name}`);
38
+ if (typeof d?.dispatch !== "string")
39
+ add("artifact.effects.dispatch", `effect "${name}" needs a dispatch action name`, `effects.${name}`);
40
+ }
41
+ return { valid: v.length === 0, violations: v };
42
+ }
43
+ //# sourceMappingURL=validate-artifact.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validate-artifact.js","sourceRoot":"","sources":["../src/validate-artifact.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import type { ValidationResult } from "./types.js";
2
+ export declare function validateObixAST(ast: unknown): ValidationResult;
3
+ //# sourceMappingURL=validate-ast.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validate-ast.d.ts","sourceRoot":"","sources":["../src/validate-ast.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,gBAAgB,EAIjB,MAAM,YAAY,CAAC;AAgBpB,wBAAgB,eAAe,CAAC,GAAG,EAAE,OAAO,GAAG,gBAAgB,CAqC9D"}
@@ -0,0 +1,84 @@
1
+ const IDENT = /^[A-Za-z_$][\w$]*$/;
2
+ const PATH = /^[A-Za-z_$][\w$]*(?:\.[A-Za-z_$][\w$]*)*$/;
3
+ const PASCAL = /^[A-Z][A-Za-z0-9]*$/;
4
+ const TAG = /^[a-z][a-z0-9-]*$/;
5
+ export function validateObixAST(ast) {
6
+ const v = [];
7
+ const add = (rule, message, path) => v.push({ rule, message, path });
8
+ if (typeof ast !== "object" || ast === null) {
9
+ return { valid: false, violations: [{ rule: "ast.object", message: "AST must be an object" }] };
10
+ }
11
+ const a = ast;
12
+ if (typeof a.componentName !== "string" || !PASCAL.test(a.componentName)) {
13
+ add("ast.componentName", "componentName must be a PascalCase string", "componentName");
14
+ }
15
+ const sections = (a.sections ?? {});
16
+ if (!sections.template)
17
+ add("ast.sections.template", "a <template> section is required", "sections.template");
18
+ if (!sections.script)
19
+ add("ast.sections.script", "a <script> section is required", "sections.script");
20
+ if (a.template !== undefined) {
21
+ if (!isElement(a.template)) {
22
+ add("template.root", "template root must be a single element node", "template");
23
+ }
24
+ else {
25
+ walk(a.template, [], add);
26
+ }
27
+ }
28
+ if (a.script !== undefined) {
29
+ const s = a.script;
30
+ if (!Array.isArray(s.actionNames)) {
31
+ add("script.actionNames", "script model must expose actionNames[]", "script.actionNames");
32
+ }
33
+ else {
34
+ for (const n of s.actionNames) {
35
+ if (typeof n !== "string" || !IDENT.test(n))
36
+ add("script.actionNames", `invalid action name: ${String(n)}`, "script.actionNames");
37
+ }
38
+ }
39
+ }
40
+ return { valid: v.length === 0, violations: v };
41
+ }
42
+ function isElement(n) {
43
+ return typeof n === "object" && n !== null && n.kind === "element";
44
+ }
45
+ function walk(node, path, add) {
46
+ const at = path.join(".");
47
+ if (node.kind === "element") {
48
+ if (typeof node.tag !== "string" || !TAG.test(node.tag)) {
49
+ add("template.element.tag", `invalid tag "${String(node.tag)}"`, at);
50
+ }
51
+ if (!Array.isArray(node.attrs)) {
52
+ add("template.element.attrs", "element attrs must be an array", at);
53
+ }
54
+ else {
55
+ for (const attr of node.attrs) {
56
+ if (typeof attr.name !== "string" || attr.name.length === 0) {
57
+ add("template.attr.name", "attribute name must be a non-empty string", at);
58
+ }
59
+ if (attr.interpolation !== undefined && !PATH.test(attr.interpolation)) {
60
+ add("template.attr.interpolation", `attribute "${attr.name}" interpolation must be an identifier or dotted path, got "${attr.interpolation}"`, at);
61
+ }
62
+ if (attr.name.startsWith("on:")) {
63
+ const action = attr.value ?? attr.interpolation ?? "";
64
+ if (!IDENT.test(action))
65
+ add("template.event", `on:${attr.name.slice(3)} must name an action identifier`, at);
66
+ }
67
+ }
68
+ }
69
+ node.children.forEach((child, i) => walk(child, [...path, i], add));
70
+ }
71
+ else if (node.kind === "interpolation") {
72
+ if (typeof node.expr !== "string" || !PATH.test(node.expr)) {
73
+ add("template.interpolation", `interpolation expression must be an identifier or dotted path, got "${String(node.expr)}"`, at);
74
+ }
75
+ }
76
+ else if (node.kind === "text") {
77
+ if (typeof node.value !== "string")
78
+ add("template.text", "text node value must be a string", at);
79
+ }
80
+ else {
81
+ add("template.node.kind", `unknown template node kind "${String(node.kind)}"`, at);
82
+ }
83
+ }
84
+ //# sourceMappingURL=validate-ast.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validate-ast.js","sourceRoot":"","sources":["../src/validate-ast.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ export declare const SPEC_VERSION: "0.2.1";
2
+ export declare const LEVEL: 0;
3
+ export type ObixLevel = 0 | 1 | 2;
4
+ //# sourceMappingURL=version.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"version.d.ts","sourceRoot":"","sources":["../src/version.ts"],"names":[],"mappings":"AACA,eAAO,MAAM,YAAY,EAAG,OAAgB,CAAC;AAG7C,eAAO,MAAM,KAAK,EAAG,CAAU,CAAC;AAEhC,MAAM,MAAM,SAAS,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC"}
@@ -0,0 +1,3 @@
1
+ export const SPEC_VERSION = "0.2.1";
2
+ export const LEVEL = 0;
3
+ //# sourceMappingURL=version.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"version.js","sourceRoot":"","sources":["../src/version.ts"],"names":[],"mappings":"AACA,MAAM,CAAC,MAAM,YAAY,GAAG,OAAgB,CAAC;AAG7C,MAAM,CAAC,MAAM,KAAK,GAAG,CAAU,CAAC"}
package/package.json ADDED
@@ -0,0 +1,34 @@
1
+ {
2
+ "name": "obix-spec",
3
+ "version": "0.2.1",
4
+ "description": "OBIX canonical types, structural contracts, and the one scope-token function. Zero runtime dependencies. The single source of truth for every OBIX interface.",
5
+ "license": "MIT",
6
+ "type": "module",
7
+ "private": false,
8
+ "sideEffects": false,
9
+ "main": "./dist/index.js",
10
+ "types": "./dist/index.d.ts",
11
+ "exports": {
12
+ ".": {
13
+ "types": "./dist/index.d.ts",
14
+ "import": "./dist/index.js"
15
+ },
16
+ "./package.json": "./package.json"
17
+ },
18
+ "files": ["dist", "README.md", "LICENSE"],
19
+ "scripts": {
20
+ "build": "tsc -p tsconfig.json",
21
+ "clean": "node -e \"require('fs').rmSync('dist',{recursive:true,force:true})\""
22
+ },
23
+ "publishConfig": {
24
+ "access": "public"
25
+ },
26
+ "engines": {
27
+ "node": ">=20.11.0"
28
+ },
29
+ "repository": {
30
+ "type": "git",
31
+ "url": "git+https://github.com/obinexusmk2/obix-monorepo-2026.git",
32
+ "directory": "packages/obix-spec"
33
+ }
34
+ }