juxscript 1.0.88 → 1.0.90

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.
Files changed (89) hide show
  1. package/bin/cli.js +243 -92
  2. package/index.js +21 -0
  3. package/lib/componentsv2/base/BaseEngine.d.ts +10 -0
  4. package/lib/componentsv2/base/BaseEngine.d.ts.map +1 -1
  5. package/lib/componentsv2/base/BaseEngine.js +28 -7
  6. package/lib/componentsv2/base/BaseEngine.js.map +1 -1
  7. package/lib/componentsv2/base/BaseEngine.ts +29 -0
  8. package/lib/componentsv2/base/OptionsContract.d.ts +20 -0
  9. package/lib/componentsv2/base/OptionsContract.d.ts.map +1 -0
  10. package/lib/componentsv2/base/OptionsContract.js +107 -0
  11. package/lib/componentsv2/base/OptionsContract.js.map +1 -0
  12. package/lib/componentsv2/base/OptionsContract.ts +139 -0
  13. package/lib/componentsv2/element/component.d.ts +22 -0
  14. package/lib/componentsv2/element/component.d.ts.map +1 -1
  15. package/lib/componentsv2/element/component.js +22 -0
  16. package/lib/componentsv2/element/component.js.map +1 -1
  17. package/lib/componentsv2/element/component.ts +23 -1
  18. package/lib/componentsv2/element/engine.d.ts +31 -14
  19. package/lib/componentsv2/element/engine.d.ts.map +1 -1
  20. package/lib/componentsv2/element/engine.js +74 -23
  21. package/lib/componentsv2/element/engine.js.map +1 -1
  22. package/lib/componentsv2/element/engine.ts +86 -29
  23. package/lib/componentsv2/element/skin.d.ts.map +1 -1
  24. package/lib/componentsv2/element/skin.js +7 -10
  25. package/lib/componentsv2/element/skin.js.map +1 -1
  26. package/lib/componentsv2/element/skin.ts +7 -11
  27. package/lib/componentsv2/grid/engine.d.ts +48 -3
  28. package/lib/componentsv2/grid/engine.d.ts.map +1 -1
  29. package/lib/componentsv2/grid/engine.js +109 -14
  30. package/lib/componentsv2/grid/engine.js.map +1 -1
  31. package/lib/componentsv2/grid/engine.ts +120 -16
  32. package/lib/componentsv2/input/engine.d.ts +48 -5
  33. package/lib/componentsv2/input/engine.d.ts.map +1 -1
  34. package/lib/componentsv2/input/engine.js +108 -15
  35. package/lib/componentsv2/input/engine.js.map +1 -1
  36. package/lib/componentsv2/input/engine.ts +119 -16
  37. package/lib/componentsv2/input/skin.d.ts.map +1 -1
  38. package/lib/componentsv2/input/skin.js +1 -4
  39. package/lib/componentsv2/input/skin.js.map +1 -1
  40. package/lib/componentsv2/input/skin.ts +1 -4
  41. package/lib/componentsv2/list/component.d.ts +28 -6
  42. package/lib/componentsv2/list/component.d.ts.map +1 -1
  43. package/lib/componentsv2/list/component.js +28 -6
  44. package/lib/componentsv2/list/component.js.map +1 -1
  45. package/lib/componentsv2/list/component.ts +28 -6
  46. package/lib/componentsv2/list/engine.d.ts +61 -9
  47. package/lib/componentsv2/list/engine.d.ts.map +1 -1
  48. package/lib/componentsv2/list/engine.js +156 -95
  49. package/lib/componentsv2/list/engine.js.map +1 -1
  50. package/lib/componentsv2/list/engine.ts +175 -108
  51. package/machinery/build3.js +21 -0
  52. package/machinery/compiler3.js +638 -0
  53. package/machinery/serve.js +255 -0
  54. package/machinery/watcher.js +53 -64
  55. package/package.json +11 -3
  56. package/lib/componentsv2/index.d.ts +0 -41
  57. package/lib/componentsv2/index.d.ts.map +0 -1
  58. package/lib/componentsv2/index.js +0 -223
  59. package/lib/componentsv2/index.js.map +0 -1
  60. package/lib/componentsv2/index.ts +0 -256
  61. package/lib/componentsv2/juxerror/component.d.ts +0 -28
  62. package/lib/componentsv2/juxerror/component.d.ts.map +0 -1
  63. package/lib/componentsv2/juxerror/component.js +0 -101
  64. package/lib/componentsv2/juxerror/component.js.map +0 -1
  65. package/lib/componentsv2/juxerror/component.ts +0 -125
  66. package/lib/componentsv2/juxerror/engine.d.ts +0 -35
  67. package/lib/componentsv2/juxerror/engine.d.ts.map +0 -1
  68. package/lib/componentsv2/juxerror/engine.js +0 -190
  69. package/lib/componentsv2/juxerror/engine.js.map +0 -1
  70. package/lib/componentsv2/juxerror/engine.ts +0 -241
  71. package/lib/componentsv2/juxerror/skin.d.ts +0 -11
  72. package/lib/componentsv2/juxerror/skin.d.ts.map +0 -1
  73. package/lib/componentsv2/juxerror/skin.js +0 -180
  74. package/lib/componentsv2/juxerror/skin.js.map +0 -1
  75. package/lib/componentsv2/juxerror/skin.ts +0 -200
  76. package/lib/componentsv2/juxerror/structure.css +0 -351
  77. package/machinery/ast.js +0 -347
  78. package/machinery/compiler.js +0 -706
  79. package/machinery/diagnose.js +0 -72
  80. package/machinery/doc-generator.js +0 -136
  81. package/machinery/imports.js +0 -155
  82. package/machinery/jux-module-pattern.md +0 -118
  83. package/machinery/server.js +0 -86
  84. package/machinery/ts-shim.js +0 -46
  85. package/machinery/verifier.js +0 -135
  86. package/tests/dropdown-test.js +0 -25
  87. package/tests/juxerrors/bad_syntax.jux +0 -8
  88. package/tests/juxerrors/ghost_dep.jux +0 -10
  89. package/tests/server_plugin_test.ts +0 -191
@@ -0,0 +1,107 @@
1
+ /**
2
+ * Validates user-provided options against a defined contract schema.
3
+ * Emits warnings for unknown/misnamed options and errors for type mismatches.
4
+ */
5
+ export function validateOptions(componentName, userOptions, schema, debugMode = false) {
6
+ const result = {
7
+ valid: true,
8
+ warnings: [],
9
+ errors: [],
10
+ normalized: {}
11
+ };
12
+ const validKeys = new Set(Object.keys(schema));
13
+ const aliasMap = new Map();
14
+ // Build alias lookup
15
+ for (const [key, def] of Object.entries(schema)) {
16
+ if (def.aliases) {
17
+ def.aliases.forEach(alias => aliasMap.set(alias.toLowerCase(), key));
18
+ }
19
+ }
20
+ // Check for unknown or aliased options
21
+ for (const [key, value] of Object.entries(userOptions)) {
22
+ const lowerKey = key.toLowerCase();
23
+ if (validKeys.has(key)) {
24
+ // Valid key - validate type
25
+ const def = schema[key];
26
+ if (!validateType(value, def.type)) {
27
+ result.errors.push(`[${componentName}] Option "${key}" expects type "${def.type}", got "${typeof value}".`);
28
+ result.valid = false;
29
+ }
30
+ else {
31
+ result.normalized[key] = value;
32
+ }
33
+ }
34
+ else if (aliasMap.has(lowerKey)) {
35
+ // Found an alias - warn and normalize
36
+ const correctKey = aliasMap.get(lowerKey);
37
+ result.warnings.push(`[${componentName}] Option "${key}" is not valid. Did you mean "${correctKey}"?`);
38
+ result.normalized[correctKey] = value;
39
+ }
40
+ else {
41
+ // Unknown option
42
+ const suggestion = findClosestMatch(key, Array.from(validKeys));
43
+ const hint = suggestion ? ` Did you mean "${suggestion}"?` : '';
44
+ result.warnings.push(`[${componentName}] Unknown option "${key}".${hint} Valid options: ${Array.from(validKeys).join(', ')}`);
45
+ }
46
+ }
47
+ // Apply defaults for missing required options
48
+ for (const [key, def] of Object.entries(schema)) {
49
+ if (!(key in result.normalized)) {
50
+ if (def.required && def.default === undefined) {
51
+ result.errors.push(`[${componentName}] Required option "${key}" is missing.`);
52
+ result.valid = false;
53
+ }
54
+ else if (def.default !== undefined) {
55
+ result.normalized[key] = def.default;
56
+ }
57
+ }
58
+ }
59
+ // Log warnings/errors in debug mode
60
+ if (debugMode || result.warnings.length || result.errors.length) {
61
+ result.warnings.forEach(w => console.warn(w));
62
+ result.errors.forEach(e => console.error(e));
63
+ }
64
+ return result;
65
+ }
66
+ function validateType(value, expectedType) {
67
+ if (value === undefined || value === null)
68
+ return true; // Allow optional
69
+ switch (expectedType) {
70
+ case 'string': return typeof value === 'string';
71
+ case 'number': return typeof value === 'number';
72
+ case 'boolean': return typeof value === 'boolean';
73
+ case 'array': return Array.isArray(value);
74
+ case 'object': return typeof value === 'object' && !Array.isArray(value);
75
+ case 'function': return typeof value === 'function';
76
+ default: return true;
77
+ }
78
+ }
79
+ function findClosestMatch(input, candidates) {
80
+ const lower = input.toLowerCase();
81
+ let best = null;
82
+ let bestScore = Infinity;
83
+ for (const candidate of candidates) {
84
+ const score = levenshtein(lower, candidate.toLowerCase());
85
+ if (score < bestScore && score <= 3) { // Max 3 edits
86
+ bestScore = score;
87
+ best = candidate;
88
+ }
89
+ }
90
+ return best;
91
+ }
92
+ function levenshtein(a, b) {
93
+ const matrix = [];
94
+ for (let i = 0; i <= b.length; i++)
95
+ matrix[i] = [i];
96
+ for (let j = 0; j <= a.length; j++)
97
+ matrix[0][j] = j;
98
+ for (let i = 1; i <= b.length; i++) {
99
+ for (let j = 1; j <= a.length; j++) {
100
+ matrix[i][j] = b[i - 1] === a[j - 1]
101
+ ? matrix[i - 1][j - 1]
102
+ : Math.min(matrix[i - 1][j - 1] + 1, matrix[i][j - 1] + 1, matrix[i - 1][j] + 1);
103
+ }
104
+ }
105
+ return matrix[b.length][a.length];
106
+ }
107
+ //# sourceMappingURL=OptionsContract.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"OptionsContract.js","sourceRoot":"","sources":["OptionsContract.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,139 @@
1
+ export interface OptionDefinition {
2
+ type: 'string' | 'number' | 'boolean' | 'array' | 'object' | 'function';
3
+ required?: boolean;
4
+ default?: any;
5
+ description?: string;
6
+ aliases?: string[]; // Common misspellings or alternate names
7
+ }
8
+
9
+ export type OptionsContractSchema = Record<string, OptionDefinition>;
10
+
11
+ export interface ValidationResult {
12
+ valid: boolean;
13
+ warnings: string[];
14
+ errors: string[];
15
+ normalized: Record<string, any>;
16
+ }
17
+
18
+ /**
19
+ * Validates user-provided options against a defined contract schema.
20
+ * Emits warnings for unknown/misnamed options and errors for type mismatches.
21
+ */
22
+ export function validateOptions<T extends Record<string, any>>(
23
+ componentName: string,
24
+ userOptions: Record<string, any>,
25
+ schema: OptionsContractSchema,
26
+ debugMode: boolean = false
27
+ ): ValidationResult {
28
+ const result: ValidationResult = {
29
+ valid: true,
30
+ warnings: [],
31
+ errors: [],
32
+ normalized: {}
33
+ };
34
+
35
+ const validKeys = new Set(Object.keys(schema));
36
+ const aliasMap = new Map<string, string>();
37
+
38
+ // Build alias lookup
39
+ for (const [key, def] of Object.entries(schema)) {
40
+ if (def.aliases) {
41
+ def.aliases.forEach(alias => aliasMap.set(alias.toLowerCase(), key));
42
+ }
43
+ }
44
+
45
+ // Check for unknown or aliased options
46
+ for (const [key, value] of Object.entries(userOptions)) {
47
+ const lowerKey = key.toLowerCase();
48
+
49
+ if (validKeys.has(key)) {
50
+ // Valid key - validate type
51
+ const def = schema[key];
52
+ if (!validateType(value, def.type)) {
53
+ result.errors.push(
54
+ `[${componentName}] Option "${key}" expects type "${def.type}", got "${typeof value}".`
55
+ );
56
+ result.valid = false;
57
+ } else {
58
+ result.normalized[key] = value;
59
+ }
60
+ } else if (aliasMap.has(lowerKey)) {
61
+ // Found an alias - warn and normalize
62
+ const correctKey = aliasMap.get(lowerKey)!;
63
+ result.warnings.push(
64
+ `[${componentName}] Option "${key}" is not valid. Did you mean "${correctKey}"?`
65
+ );
66
+ result.normalized[correctKey] = value;
67
+ } else {
68
+ // Unknown option
69
+ const suggestion = findClosestMatch(key, Array.from(validKeys));
70
+ const hint = suggestion ? ` Did you mean "${suggestion}"?` : '';
71
+ result.warnings.push(
72
+ `[${componentName}] Unknown option "${key}".${hint} Valid options: ${Array.from(validKeys).join(', ')}`
73
+ );
74
+ }
75
+ }
76
+
77
+ // Apply defaults for missing required options
78
+ for (const [key, def] of Object.entries(schema)) {
79
+ if (!(key in result.normalized)) {
80
+ if (def.required && def.default === undefined) {
81
+ result.errors.push(`[${componentName}] Required option "${key}" is missing.`);
82
+ result.valid = false;
83
+ } else if (def.default !== undefined) {
84
+ result.normalized[key] = def.default;
85
+ }
86
+ }
87
+ }
88
+
89
+ // Log warnings/errors in debug mode
90
+ if (debugMode || result.warnings.length || result.errors.length) {
91
+ result.warnings.forEach(w => console.warn(w));
92
+ result.errors.forEach(e => console.error(e));
93
+ }
94
+
95
+ return result;
96
+ }
97
+
98
+ function validateType(value: any, expectedType: string): boolean {
99
+ if (value === undefined || value === null) return true; // Allow optional
100
+ switch (expectedType) {
101
+ case 'string': return typeof value === 'string';
102
+ case 'number': return typeof value === 'number';
103
+ case 'boolean': return typeof value === 'boolean';
104
+ case 'array': return Array.isArray(value);
105
+ case 'object': return typeof value === 'object' && !Array.isArray(value);
106
+ case 'function': return typeof value === 'function';
107
+ default: return true;
108
+ }
109
+ }
110
+
111
+ function findClosestMatch(input: string, candidates: string[]): string | null {
112
+ const lower = input.toLowerCase();
113
+ let best: string | null = null;
114
+ let bestScore = Infinity;
115
+
116
+ for (const candidate of candidates) {
117
+ const score = levenshtein(lower, candidate.toLowerCase());
118
+ if (score < bestScore && score <= 3) { // Max 3 edits
119
+ bestScore = score;
120
+ best = candidate;
121
+ }
122
+ }
123
+ return best;
124
+ }
125
+
126
+ function levenshtein(a: string, b: string): number {
127
+ const matrix: number[][] = [];
128
+ for (let i = 0; i <= b.length; i++) matrix[i] = [i];
129
+ for (let j = 0; j <= a.length; j++) matrix[0][j] = j;
130
+
131
+ for (let i = 1; i <= b.length; i++) {
132
+ for (let j = 1; j <= a.length; j++) {
133
+ matrix[i][j] = b[i - 1] === a[j - 1]
134
+ ? matrix[i - 1][j - 1]
135
+ : Math.min(matrix[i - 1][j - 1] + 1, matrix[i][j - 1] + 1, matrix[i - 1][j] + 1);
136
+ }
137
+ }
138
+ return matrix[b.length][a.length];
139
+ }
@@ -3,5 +3,27 @@ export type ElementComponent = ElementEngine & {
3
3
  render: (targetId: string | HTMLElement) => ElementComponent;
4
4
  injectCSS: (id: string, cssContent: string) => void;
5
5
  };
6
+ /**
7
+ * OPTIONS CONTRACT for Element:
8
+ *
9
+ * | Option | Type | Default | Aliases |
10
+ * |--------------|--------|---------|----------------------------------|
11
+ * | tagName | string | 'div' | tag, element, type |
12
+ * | content | string | '' | text, html, innerHTML, value |
13
+ * | contentType | string | 'text' | type, mode |
14
+ * | inlineStyle | string | '' | style, css, styles |
15
+ *
16
+ * METHODS (match state properties):
17
+ * - .tagName(value) - Set HTML tag
18
+ * - .content(value, type) - Set content with type
19
+ * - .contentType(type) - Set content type
20
+ * - .inlineStyle(css) - Set inline styles
21
+ *
22
+ * CONVENIENCE ALIASES:
23
+ * - .tag(value) → .tagName(value)
24
+ * - .text(value) → .content(value, 'text')
25
+ * - .html(value) → .content(value, 'html')
26
+ * - .style(css) → .inlineStyle(css)
27
+ */
6
28
  export declare function Element(id: string, options?: ElementOptions): ElementComponent;
7
29
  //# sourceMappingURL=component.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"component.d.ts","sourceRoot":"","sources":["component.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAG5D,MAAM,MAAM,gBAAgB,GAAG,aAAa,GAAG;IAC3C,MAAM,EAAE,CAAC,QAAQ,EAAE,MAAM,GAAG,WAAW,KAAK,gBAAgB,CAAC;IAC7D,SAAS,EAAE,CAAC,EAAE,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,KAAK,IAAI,CAAC;CACvD,CAAC;AAEF,wBAAgB,OAAO,CAAC,EAAE,EAAE,MAAM,EAAE,OAAO,GAAE,cAAmB,GAAG,gBAAgB,CAuBlF"}
1
+ {"version":3,"file":"component.d.ts","sourceRoot":"","sources":["component.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAG5D,MAAM,MAAM,gBAAgB,GAAG,aAAa,GAAG;IAC3C,MAAM,EAAE,CAAC,QAAQ,EAAE,MAAM,GAAG,WAAW,KAAK,gBAAgB,CAAC;IAC7D,SAAS,EAAE,CAAC,EAAE,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,KAAK,IAAI,CAAC;CACvD,CAAC;AAEF;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAgB,OAAO,CAAC,EAAE,EAAE,MAAM,EAAE,OAAO,GAAE,cAAmB,GAAG,gBAAgB,CAuBlF"}
@@ -1,5 +1,27 @@
1
1
  import { ElementEngine } from './engine.js';
2
2
  import { ElementSkin } from './skin.js';
3
+ /**
4
+ * OPTIONS CONTRACT for Element:
5
+ *
6
+ * | Option | Type | Default | Aliases |
7
+ * |--------------|--------|---------|----------------------------------|
8
+ * | tagName | string | 'div' | tag, element, type |
9
+ * | content | string | '' | text, html, innerHTML, value |
10
+ * | contentType | string | 'text' | type, mode |
11
+ * | inlineStyle | string | '' | style, css, styles |
12
+ *
13
+ * METHODS (match state properties):
14
+ * - .tagName(value) - Set HTML tag
15
+ * - .content(value, type) - Set content with type
16
+ * - .contentType(type) - Set content type
17
+ * - .inlineStyle(css) - Set inline styles
18
+ *
19
+ * CONVENIENCE ALIASES:
20
+ * - .tag(value) → .tagName(value)
21
+ * - .text(value) → .content(value, 'text')
22
+ * - .html(value) → .content(value, 'html')
23
+ * - .style(css) → .inlineStyle(css)
24
+ */
3
25
  export function Element(id, options = {}) {
4
26
  const engine = new ElementEngine(id, options);
5
27
  if (typeof window !== 'undefined') {
@@ -1 +1 @@
1
- {"version":3,"file":"component.js","sourceRoot":"","sources":["component.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAkB,MAAM,aAAa,CAAC;AAC5D,OAAO,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AAOxC,MAAM,UAAU,OAAO,CAAC,EAAU,EAAE,UAA0B,EAAE;IAC5D,MAAM,MAAM,GAAG,IAAI,aAAa,CAAC,EAAE,EAAE,OAAO,CAAC,CAAC;IAE9C,IAAI,OAAO,MAAM,KAAK,WAAW,EAAE,CAAC;QAChC,aAAa;QACb,MAAM,CAAC,UAAU,GAAG,MAAM,CAAC,UAAU,IAAI,EAAE,CAAC;QAC5C,aAAa;QACb,MAAM,CAAC,UAAU,CAAC,EAAE,CAAC,GAAG,MAAM,CAAC;IACnC,CAAC;IAED,MAAM,IAAI,GAAG,IAAI,WAAW,CAAC,MAAM,CAAC,CAAC;IAErC,aAAa;IACb,MAAM,CAAC,MAAM,GAAG,CAAC,QAA8B,EAAE,EAAE;QAC/C,MAAM,MAAM,GAAG,OAAO,QAAQ,KAAK,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,cAAc,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC;QAC3F,IAAI,MAAM;YAAE,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC;QACpC,OAAO,MAA0B,CAAC;IACtC,CAAC,CAAC;IAEF,aAAa;IACb,MAAM,CAAC,SAAS,GAAG,CAAC,EAAE,EAAE,GAAG,EAAE,EAAE,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,EAAE,GAAG,CAAC,CAAC;IAExD,OAAO,MAA0B,CAAC;AACtC,CAAC"}
1
+ {"version":3,"file":"component.js","sourceRoot":"","sources":["component.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAkB,MAAM,aAAa,CAAC;AAC5D,OAAO,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AAOxC;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,MAAM,UAAU,OAAO,CAAC,EAAU,EAAE,UAA0B,EAAE;IAC5D,MAAM,MAAM,GAAG,IAAI,aAAa,CAAC,EAAE,EAAE,OAAO,CAAC,CAAC;IAE9C,IAAI,OAAO,MAAM,KAAK,WAAW,EAAE,CAAC;QAChC,aAAa;QACb,MAAM,CAAC,UAAU,GAAG,MAAM,CAAC,UAAU,IAAI,EAAE,CAAC;QAC5C,aAAa;QACb,MAAM,CAAC,UAAU,CAAC,EAAE,CAAC,GAAG,MAAM,CAAC;IACnC,CAAC;IAED,MAAM,IAAI,GAAG,IAAI,WAAW,CAAC,MAAM,CAAC,CAAC;IAErC,aAAa;IACb,MAAM,CAAC,MAAM,GAAG,CAAC,QAA8B,EAAE,EAAE;QAC/C,MAAM,MAAM,GAAG,OAAO,QAAQ,KAAK,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,cAAc,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC;QAC3F,IAAI,MAAM;YAAE,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC;QACpC,OAAO,MAA0B,CAAC;IACtC,CAAC,CAAC;IAEF,aAAa;IACb,MAAM,CAAC,SAAS,GAAG,CAAC,EAAU,EAAE,GAAW,EAAE,EAAE,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,EAAE,GAAG,CAAC,CAAC;IAExE,OAAO,MAA0B,CAAC;AACtC,CAAC"}
@@ -6,6 +6,28 @@ export type ElementComponent = ElementEngine & {
6
6
  injectCSS: (id: string, cssContent: string) => void;
7
7
  };
8
8
 
9
+ /**
10
+ * OPTIONS CONTRACT for Element:
11
+ *
12
+ * | Option | Type | Default | Aliases |
13
+ * |--------------|--------|---------|----------------------------------|
14
+ * | tagName | string | 'div' | tag, element, type |
15
+ * | content | string | '' | text, html, innerHTML, value |
16
+ * | contentType | string | 'text' | type, mode |
17
+ * | inlineStyle | string | '' | style, css, styles |
18
+ *
19
+ * METHODS (match state properties):
20
+ * - .tagName(value) - Set HTML tag
21
+ * - .content(value, type) - Set content with type
22
+ * - .contentType(type) - Set content type
23
+ * - .inlineStyle(css) - Set inline styles
24
+ *
25
+ * CONVENIENCE ALIASES:
26
+ * - .tag(value) → .tagName(value)
27
+ * - .text(value) → .content(value, 'text')
28
+ * - .html(value) → .content(value, 'html')
29
+ * - .style(css) → .inlineStyle(css)
30
+ */
9
31
  export function Element(id: string, options: ElementOptions = {}): ElementComponent {
10
32
  const engine = new ElementEngine(id, options);
11
33
 
@@ -26,7 +48,7 @@ export function Element(id: string, options: ElementOptions = {}): ElementCompon
26
48
  };
27
49
 
28
50
  // @ts-ignore
29
- engine.injectCSS = (id, css) => skin.injectCSS(id, css);
51
+ engine.injectCSS = (id: string, css: string) => skin.injectCSS(id, css);
30
52
 
31
53
  return engine as ElementComponent;
32
54
  }
@@ -1,4 +1,5 @@
1
1
  import { BaseEngine, BaseState } from '../base/BaseEngine.js';
2
+ import { OptionsContractSchema } from '../base/OptionsContract.js';
2
3
  export interface ElementState extends BaseState {
3
4
  tagName: string;
4
5
  content: string | null;
@@ -6,37 +7,53 @@ export interface ElementState extends BaseState {
6
7
  inlineStyle: string;
7
8
  }
8
9
  export interface ElementOptions {
9
- tag?: string;
10
- text?: string;
11
- html?: string;
12
- style?: string;
10
+ tagName?: string;
11
+ content?: string;
12
+ contentType?: 'text' | 'html';
13
+ inlineStyle?: string;
13
14
  }
14
15
  export declare class ElementEngine extends BaseEngine<ElementState, ElementOptions> {
15
16
  constructor(id: string, options?: ElementOptions);
17
+ /**
18
+ * OPTIONS CONTRACT
19
+ * Defines valid options with types, defaults, and aliases for common mistakes.
20
+ */
21
+ protected get optionsSchema(): OptionsContractSchema;
16
22
  protected prepareState(id: string, options: ElementOptions): ElementState;
17
23
  /**
18
- * Set the HTML Tag name (e.g. 'div', 'span', 'h1', 'section')
24
+ * Set the HTML tag name (e.g., 'div', 'span', 'h1', 'section')
25
+ * Method name matches state property: tagName
19
26
  */
20
- tag(tagName: string): this;
27
+ tagName(value: string): this;
21
28
  /**
22
- * Set plain text content (automatically escaped)
29
+ * Set content with explicit type
30
+ * Method name matches state property: content
23
31
  */
24
- text(value: string): this;
32
+ content(value: string, type?: 'text' | 'html'): this;
33
+ /**
34
+ * Set content type
35
+ * Method name matches state property: contentType
36
+ */
37
+ contentType(type: 'text' | 'html'): this;
25
38
  /**
26
- * Set raw HTML content (innerHTML)
39
+ * Set inline styles (e.g., "color: red; margin: 10px;")
40
+ * Method name matches state property: inlineStyle
27
41
  */
42
+ inlineStyle(cssText: string): this;
43
+ /** @alias for tagName() */
44
+ tag(value: string): this;
45
+ /** @alias for content(value, 'text') */
46
+ text(value: string): this;
47
+ /** @alias for content(value, 'html') */
28
48
  html(value: string): this;
49
+ /** @alias for inlineStyle() */
50
+ style(cssText: string): this;
29
51
  /**
30
52
  * Append raw HTML to existing content
31
53
  */
32
54
  appendHtml(value: string): this;
33
- /**
34
- * Set inline styles (e.g. "color: red; margin: 10px;")
35
- */
36
- style(cssText: string): this;
37
55
  /**
38
56
  * Receives RAW DOM events from the Skin and emits them to listeners.
39
- * This keeps the 'emit' logic encapsulated within the Engine.
40
57
  */
41
58
  handleEvent(eventName: string, content: any): void;
42
59
  }
@@ -1 +1 @@
1
- {"version":3,"file":"engine.d.ts","sourceRoot":"","sources":["engine.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAE9D,MAAM,WAAW,YAAa,SAAQ,SAAS;IAC3C,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,WAAW,EAAE,MAAM,GAAG,MAAM,CAAC;IAC7B,WAAW,EAAE,MAAM,CAAC;CAEvB;AAED,MAAM,WAAW,cAAc;IAC3B,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,qBAAa,aAAc,SAAQ,UAAU,CAAC,YAAY,EAAE,cAAc,CAAC;gBAC3D,EAAE,EAAE,MAAM,EAAE,OAAO,GAAE,cAAmB;IAIpD,SAAS,CAAC,YAAY,CAAC,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,cAAc,GAAG,YAAY;IAezE;;OAEG;IACH,GAAG,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI;IAM1B;;OAEG;IACH,IAAI,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAMzB;;OAEG;IACH,IAAI,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAKzB;;OAEG;IACH,UAAU,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAM/B;;OAEG;IACH,KAAK,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI;IAK5B;;;OAGG;IACH,WAAW,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,GAAG,GAAG,IAAI;CAGrD"}
1
+ {"version":3,"file":"engine.d.ts","sourceRoot":"","sources":["engine.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAC9D,OAAO,EAAE,qBAAqB,EAAE,MAAM,4BAA4B,CAAC;AAEnE,MAAM,WAAW,YAAa,SAAQ,SAAS;IAC3C,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,WAAW,EAAE,MAAM,GAAG,MAAM,CAAC;IAC7B,WAAW,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,cAAc;IAC3B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IAC9B,WAAW,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,qBAAa,aAAc,SAAQ,UAAU,CAAC,YAAY,EAAE,cAAc,CAAC;gBAC3D,EAAE,EAAE,MAAM,EAAE,OAAO,GAAE,cAAmB;IAIpD;;;OAGG;IACH,SAAS,KAAK,aAAa,IAAI,qBAAqB,CA2BnD;IAED,SAAS,CAAC,YAAY,CAAC,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,cAAc,GAAG,YAAY;IAezE;;;OAGG;IACH,OAAO,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAM5B;;;OAGG;IACH,OAAO,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,GAAE,MAAM,GAAG,MAAe,GAAG,IAAI;IAK5D;;;OAGG;IACH,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI;IAKxC;;;OAGG;IACH,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI;IAOlC,2BAA2B;IAC3B,GAAG,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAIxB,wCAAwC;IACxC,IAAI,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAIzB,wCAAwC;IACxC,IAAI,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAIzB,+BAA+B;IAC/B,KAAK,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI;IAI5B;;OAEG;IACH,UAAU,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAM/B;;OAEG;IACH,WAAW,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,GAAG,GAAG,IAAI;CAGrD"}
@@ -3,6 +3,38 @@ export class ElementEngine extends BaseEngine {
3
3
  constructor(id, options = {}) {
4
4
  super(id, options);
5
5
  }
6
+ /**
7
+ * OPTIONS CONTRACT
8
+ * Defines valid options with types, defaults, and aliases for common mistakes.
9
+ */
10
+ get optionsSchema() {
11
+ return {
12
+ tagName: {
13
+ type: 'string',
14
+ default: 'div',
15
+ description: 'HTML tag name (e.g., "div", "span", "h1")',
16
+ aliases: ['tag', 'element', 'type']
17
+ },
18
+ content: {
19
+ type: 'string',
20
+ default: '',
21
+ description: 'Text or HTML content',
22
+ aliases: ['text', 'html', 'innerHTML', 'textContent', 'value']
23
+ },
24
+ contentType: {
25
+ type: 'string',
26
+ default: 'text',
27
+ description: 'Content type: "text" (escaped) or "html" (raw)',
28
+ aliases: ['type', 'mode']
29
+ },
30
+ inlineStyle: {
31
+ type: 'string',
32
+ default: '',
33
+ description: 'Inline CSS styles (e.g., "color: red;")',
34
+ aliases: ['style', 'css', 'styles']
35
+ }
36
+ };
37
+ }
6
38
  prepareState(id, options) {
7
39
  return {
8
40
  id,
@@ -11,53 +43,72 @@ export class ElementEngine extends BaseEngine {
11
43
  disabled: false,
12
44
  loading: false,
13
45
  attributes: {},
14
- tagName: options.tag || 'div',
15
- content: options.html || options.text || '',
16
- contentType: options.html ? 'html' : 'text',
17
- inlineStyle: options.style || '' // ✅ Initialize logic
46
+ tagName: options.tagName || 'div',
47
+ content: options.content || '',
48
+ contentType: options.contentType || 'text',
49
+ inlineStyle: options.inlineStyle || ''
18
50
  };
19
51
  }
20
52
  /**
21
- * Set the HTML Tag name (e.g. 'div', 'span', 'h1', 'section')
53
+ * Set the HTML tag name (e.g., 'div', 'span', 'h1', 'section')
54
+ * Method name matches state property: tagName
22
55
  */
23
- tag(tagName) {
24
- this.updateState({ tagName });
25
- this.emit('config', { tagName });
56
+ tagName(value) {
57
+ this.updateState({ tagName: value });
58
+ this.emit('config', { tagName: value });
26
59
  return this;
27
60
  }
28
61
  /**
29
- * Set plain text content (automatically escaped)
62
+ * Set content with explicit type
63
+ * Method name matches state property: content
30
64
  */
31
- text(value) {
32
- this.updateState({ content: value, contentType: 'text' });
33
- // No emit needed, state update triggers paint
65
+ content(value, type = 'text') {
66
+ this.updateState({ content: value, contentType: type });
34
67
  return this;
35
68
  }
36
69
  /**
37
- * Set raw HTML content (innerHTML)
70
+ * Set content type
71
+ * Method name matches state property: contentType
38
72
  */
39
- html(value) {
40
- this.updateState({ content: value, contentType: 'html' });
73
+ contentType(type) {
74
+ this.updateState({ contentType: type });
41
75
  return this;
42
76
  }
43
77
  /**
44
- * Append raw HTML to existing content
78
+ * Set inline styles (e.g., "color: red; margin: 10px;")
79
+ * Method name matches state property: inlineStyle
45
80
  */
46
- appendHtml(value) {
47
- const current = this.state.content || '';
48
- this.updateState({ content: current + value, contentType: 'html' });
81
+ inlineStyle(cssText) {
82
+ this.updateState({ inlineStyle: cssText });
49
83
  return this;
50
84
  }
85
+ // --- Convenience Aliases (documented as such) ---
86
+ /** @alias for tagName() */
87
+ tag(value) {
88
+ return this.tagName(value);
89
+ }
90
+ /** @alias for content(value, 'text') */
91
+ text(value) {
92
+ return this.content(value, 'text');
93
+ }
94
+ /** @alias for content(value, 'html') */
95
+ html(value) {
96
+ return this.content(value, 'html');
97
+ }
98
+ /** @alias for inlineStyle() */
99
+ style(cssText) {
100
+ return this.inlineStyle(cssText);
101
+ }
51
102
  /**
52
- * Set inline styles (e.g. "color: red; margin: 10px;")
103
+ * Append raw HTML to existing content
53
104
  */
54
- style(cssText) {
55
- this.updateState({ inlineStyle: cssText });
105
+ appendHtml(value) {
106
+ const current = this.state.content || '';
107
+ this.updateState({ content: current + value, contentType: 'html' });
56
108
  return this;
57
109
  }
58
110
  /**
59
111
  * Receives RAW DOM events from the Skin and emits them to listeners.
60
- * This keeps the 'emit' logic encapsulated within the Engine.
61
112
  */
62
113
  handleEvent(eventName, content) {
63
114
  this.emit(eventName, content);
@@ -1 +1 @@
1
- {"version":3,"file":"engine.js","sourceRoot":"","sources":["engine.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAa,MAAM,uBAAuB,CAAC;AAiB9D,MAAM,OAAO,aAAc,SAAQ,UAAwC;IACvE,YAAY,EAAU,EAAE,UAA0B,EAAE;QAChD,KAAK,CAAC,EAAE,EAAE,OAAO,CAAC,CAAC;IACvB,CAAC;IAES,YAAY,CAAC,EAAU,EAAE,OAAuB;QACtD,OAAO;YACH,EAAE;YACF,OAAO,EAAE,CAAC,aAAa,CAAC;YACxB,OAAO,EAAE,IAAI;YACb,QAAQ,EAAE,KAAK;YACf,OAAO,EAAE,KAAK;YACd,UAAU,EAAE,EAAE;YACd,OAAO,EAAE,OAAO,CAAC,GAAG,IAAI,KAAK;YAC7B,OAAO,EAAE,OAAO,CAAC,IAAI,IAAI,OAAO,CAAC,IAAI,IAAI,EAAE;YAC3C,WAAW,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM;YAC3C,WAAW,EAAE,OAAO,CAAC,KAAK,IAAI,EAAE,CAAC,qBAAqB;SACzD,CAAC;IACN,CAAC;IAED;;OAEG;IACH,GAAG,CAAC,OAAe;QACf,IAAI,CAAC,WAAW,CAAC,EAAE,OAAO,EAAE,CAAC,CAAC;QAC9B,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,EAAE,OAAO,EAAE,CAAC,CAAC;QACjC,OAAO,IAAI,CAAC;IAChB,CAAC;IAED;;OAEG;IACH,IAAI,CAAC,KAAa;QACd,IAAI,CAAC,WAAW,CAAC,EAAE,OAAO,EAAE,KAAK,EAAE,WAAW,EAAE,MAAM,EAAE,CAAC,CAAC;QAC1D,8CAA8C;QAC9C,OAAO,IAAI,CAAC;IAChB,CAAC;IAED;;OAEG;IACH,IAAI,CAAC,KAAa;QACd,IAAI,CAAC,WAAW,CAAC,EAAE,OAAO,EAAE,KAAK,EAAE,WAAW,EAAE,MAAM,EAAE,CAAC,CAAC;QAC1D,OAAO,IAAI,CAAC;IAChB,CAAC;IAED;;OAEG;IACH,UAAU,CAAC,KAAa;QACpB,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,IAAI,EAAE,CAAC;QACzC,IAAI,CAAC,WAAW,CAAC,EAAE,OAAO,EAAE,OAAO,GAAG,KAAK,EAAE,WAAW,EAAE,MAAM,EAAE,CAAC,CAAC;QACpE,OAAO,IAAI,CAAC;IAChB,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,OAAe;QACjB,IAAI,CAAC,WAAW,CAAC,EAAE,WAAW,EAAE,OAAO,EAAE,CAAC,CAAC;QAC3C,OAAO,IAAI,CAAC;IAChB,CAAC;IAED;;;OAGG;IACH,WAAW,CAAC,SAAiB,EAAE,OAAY;QACvC,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC;IAClC,CAAC;CACJ"}
1
+ {"version":3,"file":"engine.js","sourceRoot":"","sources":["engine.ts"],"names":[],"mappings":"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"}