@hyperfixi/behaviors 2.0.0

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 (118) hide show
  1. package/dist/all.browser.global.js +116 -0
  2. package/dist/all.browser.global.js.map +1 -0
  3. package/dist/behaviors/draggable.cjs +109 -0
  4. package/dist/behaviors/draggable.cjs.map +1 -0
  5. package/dist/behaviors/draggable.d.cts +15 -0
  6. package/dist/behaviors/draggable.d.ts +15 -0
  7. package/dist/behaviors/draggable.js +14 -0
  8. package/dist/behaviors/draggable.js.map +1 -0
  9. package/dist/behaviors/removable.cjs +120 -0
  10. package/dist/behaviors/removable.cjs.map +1 -0
  11. package/dist/behaviors/removable.d.cts +15 -0
  12. package/dist/behaviors/removable.d.ts +15 -0
  13. package/dist/behaviors/removable.js +14 -0
  14. package/dist/behaviors/removable.js.map +1 -0
  15. package/dist/behaviors/resizable.cjs +146 -0
  16. package/dist/behaviors/resizable.cjs.map +1 -0
  17. package/dist/behaviors/resizable.d.cts +15 -0
  18. package/dist/behaviors/resizable.d.ts +15 -0
  19. package/dist/behaviors/resizable.js +14 -0
  20. package/dist/behaviors/resizable.js.map +1 -0
  21. package/dist/behaviors/sortable.cjs +119 -0
  22. package/dist/behaviors/sortable.cjs.map +1 -0
  23. package/dist/behaviors/sortable.d.cts +15 -0
  24. package/dist/behaviors/sortable.d.ts +15 -0
  25. package/dist/behaviors/sortable.js +14 -0
  26. package/dist/behaviors/sortable.js.map +1 -0
  27. package/dist/behaviors/toggleable.cjs +105 -0
  28. package/dist/behaviors/toggleable.cjs.map +1 -0
  29. package/dist/behaviors/toggleable.d.cts +15 -0
  30. package/dist/behaviors/toggleable.d.ts +15 -0
  31. package/dist/behaviors/toggleable.js +14 -0
  32. package/dist/behaviors/toggleable.js.map +1 -0
  33. package/dist/chunk-272NKUJ3.js +63 -0
  34. package/dist/chunk-272NKUJ3.js.map +1 -0
  35. package/dist/chunk-2NQHIHD5.js +37 -0
  36. package/dist/chunk-2NQHIHD5.js.map +1 -0
  37. package/dist/chunk-3DVDS7CT.js +170 -0
  38. package/dist/chunk-3DVDS7CT.js.map +1 -0
  39. package/dist/chunk-3Q652JQB.js +37 -0
  40. package/dist/chunk-3Q652JQB.js.map +1 -0
  41. package/dist/chunk-BWZ6EGII.js +62 -0
  42. package/dist/chunk-BWZ6EGII.js.map +1 -0
  43. package/dist/chunk-G6WR2AYR.js +52 -0
  44. package/dist/chunk-G6WR2AYR.js.map +1 -0
  45. package/dist/chunk-HMRPQWQU.js +37 -0
  46. package/dist/chunk-HMRPQWQU.js.map +1 -0
  47. package/dist/chunk-MEP6B7XW.js +37 -0
  48. package/dist/chunk-MEP6B7XW.js.map +1 -0
  49. package/dist/chunk-URBOGGW6.js +32 -0
  50. package/dist/chunk-URBOGGW6.js.map +1 -0
  51. package/dist/chunk-V5IWDPDP.js +89 -0
  52. package/dist/chunk-V5IWDPDP.js.map +1 -0
  53. package/dist/chunk-WU37DFAL.js +37 -0
  54. package/dist/chunk-WU37DFAL.js.map +1 -0
  55. package/dist/chunk-WUHHMDAA.js +48 -0
  56. package/dist/chunk-WUHHMDAA.js.map +1 -0
  57. package/dist/core.browser.global.js +39 -0
  58. package/dist/core.browser.global.js.map +1 -0
  59. package/dist/draggable.browser.global.js +25 -0
  60. package/dist/draggable.browser.global.js.map +1 -0
  61. package/dist/index.cjs +907 -0
  62. package/dist/index.cjs.map +1 -0
  63. package/dist/index.d.cts +134 -0
  64. package/dist/index.d.ts +134 -0
  65. package/dist/index.js +193 -0
  66. package/dist/index.js.map +1 -0
  67. package/dist/loaders.cjs +562 -0
  68. package/dist/loaders.cjs.map +1 -0
  69. package/dist/loaders.d.cts +2 -0
  70. package/dist/loaders.d.ts +2 -0
  71. package/dist/loaders.js +8 -0
  72. package/dist/loaders.js.map +1 -0
  73. package/dist/registry.cjs +214 -0
  74. package/dist/registry.cjs.map +1 -0
  75. package/dist/registry.d.cts +116 -0
  76. package/dist/registry.d.ts +116 -0
  77. package/dist/registry.js +47 -0
  78. package/dist/registry.js.map +1 -0
  79. package/dist/removable.browser.global.js +23 -0
  80. package/dist/removable.browser.global.js.map +1 -0
  81. package/dist/resizable.browser.global.js +35 -0
  82. package/dist/resizable.browser.global.js.map +1 -0
  83. package/dist/schemas/index.cjs +353 -0
  84. package/dist/schemas/index.cjs.map +1 -0
  85. package/dist/schemas/index.d.cts +75 -0
  86. package/dist/schemas/index.d.ts +75 -0
  87. package/dist/schemas/index.js +41 -0
  88. package/dist/schemas/index.js.map +1 -0
  89. package/dist/sortable.browser.global.js +25 -0
  90. package/dist/sortable.browser.global.js.map +1 -0
  91. package/dist/toggleable.browser.global.js +16 -0
  92. package/dist/toggleable.browser.global.js.map +1 -0
  93. package/dist/types-CCc_2wAb.d.cts +100 -0
  94. package/dist/types-CCc_2wAb.d.ts +100 -0
  95. package/package.json +109 -0
  96. package/src/behaviors/draggable.ts +60 -0
  97. package/src/behaviors/index.ts +40 -0
  98. package/src/behaviors/integration.test.ts +80 -0
  99. package/src/behaviors/removable.ts +55 -0
  100. package/src/behaviors/resizable.ts +55 -0
  101. package/src/behaviors/sortable.ts +56 -0
  102. package/src/behaviors/toggleable.ts +55 -0
  103. package/src/core-bundle.ts +35 -0
  104. package/src/generated/index.ts +9 -0
  105. package/src/generated/metadata.ts +78 -0
  106. package/src/generated/types.ts +51 -0
  107. package/src/index.test.ts +180 -0
  108. package/src/index.ts +222 -0
  109. package/src/loaders.ts +39 -0
  110. package/src/registry.test.ts +207 -0
  111. package/src/registry.ts +304 -0
  112. package/src/schemas/draggable.schema.ts +54 -0
  113. package/src/schemas/index.ts +60 -0
  114. package/src/schemas/removable.schema.ts +69 -0
  115. package/src/schemas/resizable.schema.ts +91 -0
  116. package/src/schemas/sortable.schema.ts +68 -0
  117. package/src/schemas/toggleable.schema.ts +50 -0
  118. package/src/schemas/types.ts +107 -0
@@ -0,0 +1,55 @@
1
+ /**
2
+ * Toggleable Behavior
3
+ *
4
+ * A behavior that toggles a CSS class on click.
5
+ * Useful for accordions, dropdowns, and toggle buttons.
6
+ *
7
+ * @example
8
+ * ```html
9
+ * <button _="install Toggleable">Toggle</button>
10
+ *
11
+ * <button _="install Toggleable(cls: expanded, target: #menu)">Menu</button>
12
+ * ```
13
+ */
14
+
15
+ import { toggleableSchema } from '../schemas/toggleable.schema';
16
+ import type { LokaScriptInstance, LokaScriptWindow } from '../schemas/types';
17
+
18
+ // Re-export schema-derived values for backwards compatibility
19
+ export const toggleableSource = toggleableSchema.source;
20
+ export const toggleableMetadata = toggleableSchema;
21
+
22
+ /**
23
+ * Register the Toggleable behavior with LokaScript.
24
+ */
25
+ export async function registerToggleable(hyperfixi?: LokaScriptInstance): Promise<void> {
26
+ const hf =
27
+ hyperfixi ||
28
+ (typeof window !== 'undefined' ? (window as unknown as LokaScriptWindow).lokascript : null);
29
+
30
+ if (!hf) {
31
+ throw new Error(
32
+ 'LokaScript not found. Make sure @hyperfixi/core is loaded before registering behaviors.'
33
+ );
34
+ }
35
+
36
+ const result = hf.compileSync(toggleableSchema.source, { traditional: true });
37
+
38
+ if (!result.ok) {
39
+ throw new Error(`Failed to compile Toggleable behavior: ${JSON.stringify(result.errors)}`);
40
+ }
41
+
42
+ const ctx = hf.createContext ? hf.createContext() : { locals: new Map(), globals: new Map() };
43
+ await hf.execute(result.ast, ctx);
44
+ }
45
+
46
+ // Auto-register when loaded as a script tag
47
+ if (typeof window !== 'undefined' && (window as unknown as LokaScriptWindow).lokascript) {
48
+ registerToggleable().catch(console.error);
49
+ }
50
+
51
+ export default {
52
+ source: toggleableSchema.source,
53
+ metadata: toggleableSchema,
54
+ register: registerToggleable,
55
+ };
@@ -0,0 +1,35 @@
1
+ /**
2
+ * Core Tier Bundle
3
+ *
4
+ * Includes only core tier behaviors (Draggable, Toggleable).
5
+ * Use this for minimal bundle size when you only need essential behaviors.
6
+ */
7
+
8
+ export { registerDraggable, draggableSource, draggableMetadata } from './behaviors/draggable';
9
+
10
+ export { registerToggleable, toggleableSource, toggleableMetadata } from './behaviors/toggleable';
11
+
12
+ import { registerDraggable } from './behaviors/draggable';
13
+ import { registerToggleable } from './behaviors/toggleable';
14
+ import type { LokaScriptInstance, LokaScriptWindow } from './schemas/types';
15
+
16
+ /**
17
+ * Register all core tier behaviors.
18
+ */
19
+ export async function registerCore(hyperfixi?: LokaScriptInstance): Promise<void> {
20
+ await Promise.all([registerDraggable(hyperfixi), registerToggleable(hyperfixi)]);
21
+ }
22
+
23
+ /**
24
+ * Promise that resolves when core behaviors are registered.
25
+ * Set when the package auto-registers in browser environments.
26
+ */
27
+ export let ready: Promise<void> | null = null;
28
+
29
+ // Auto-register when loaded in browser
30
+ if (typeof window !== 'undefined' && (window as unknown as LokaScriptWindow).lokascript) {
31
+ ready = registerCore();
32
+ ready.catch(err => {
33
+ console.error('[behaviors] Core auto-registration failed:', err);
34
+ });
35
+ }
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Generated Exports
3
+ *
4
+ * DO NOT EDIT - Generated by scripts/generate.ts
5
+ * Run `npm run generate` to regenerate.
6
+ */
7
+
8
+ export * from './types';
9
+ export * from './metadata';
@@ -0,0 +1,78 @@
1
+ /**
2
+ * Generated Metadata
3
+ *
4
+ * DO NOT EDIT - Generated by scripts/generate.ts
5
+ * Run `npm run generate` to regenerate.
6
+ */
7
+
8
+ import type { BehaviorCategory, BehaviorTier } from '../schemas/types';
9
+ import type { BehaviorName } from './types';
10
+
11
+ /**
12
+ * All behavior names.
13
+ */
14
+ export const ALL_BEHAVIOR_NAMES: BehaviorName[] = [
15
+ "Draggable",
16
+ "Sortable",
17
+ "Resizable",
18
+ "Removable",
19
+ "Toggleable"
20
+ ];
21
+
22
+ /**
23
+ * Behaviors grouped by category.
24
+ */
25
+ export const BEHAVIORS_BY_CATEGORY: Record<BehaviorCategory, BehaviorName[]> = {
26
+ "ui": [
27
+ "Draggable",
28
+ "Sortable",
29
+ "Resizable"
30
+ ],
31
+ "data": [
32
+ "Removable"
33
+ ],
34
+ "animation": [],
35
+ "form": [
36
+ "Toggleable"
37
+ ],
38
+ "layout": []
39
+ };
40
+
41
+ /**
42
+ * Behaviors grouped by tier.
43
+ */
44
+ export const BEHAVIORS_BY_TIER: Record<BehaviorTier, BehaviorName[]> = {
45
+ "core": [
46
+ "Draggable",
47
+ "Toggleable"
48
+ ],
49
+ "common": [
50
+ "Sortable",
51
+ "Removable"
52
+ ],
53
+ "optional": [
54
+ "Resizable"
55
+ ]
56
+ };
57
+
58
+ /**
59
+ * Category for each behavior.
60
+ */
61
+ export const BEHAVIOR_CATEGORIES: Record<BehaviorName, BehaviorCategory> = {
62
+ "Draggable": "ui",
63
+ "Sortable": "ui",
64
+ "Resizable": "ui",
65
+ "Removable": "data",
66
+ "Toggleable": "form"
67
+ };
68
+
69
+ /**
70
+ * Tier for each behavior.
71
+ */
72
+ export const BEHAVIOR_TIERS: Record<BehaviorName, BehaviorTier> = {
73
+ "Draggable": "core",
74
+ "Sortable": "common",
75
+ "Resizable": "optional",
76
+ "Removable": "common",
77
+ "Toggleable": "core"
78
+ };
@@ -0,0 +1,51 @@
1
+ /**
2
+ * Generated Types
3
+ *
4
+ * DO NOT EDIT - Generated by scripts/generate.ts
5
+ * Run `npm run generate` to regenerate.
6
+ */
7
+
8
+ /**
9
+ * Union of all behavior names.
10
+ */
11
+ export type BehaviorName = 'Draggable' | 'Sortable' | 'Resizable' | 'Removable' | 'Toggleable';
12
+
13
+ /**
14
+ * UI category behaviors.
15
+ */
16
+ export type UIBehavior = 'Draggable' | 'Sortable' | 'Resizable';
17
+
18
+ /**
19
+ * Data category behaviors.
20
+ */
21
+ export type DataBehavior = 'Removable';
22
+
23
+ /**
24
+ * Animation category behaviors.
25
+ */
26
+ export type AnimationBehavior = never;
27
+
28
+ /**
29
+ * Form category behaviors.
30
+ */
31
+ export type FormBehavior = 'Toggleable';
32
+
33
+ /**
34
+ * Layout category behaviors.
35
+ */
36
+ export type LayoutBehavior = never;
37
+
38
+ /**
39
+ * Core tier behaviors (always loaded).
40
+ */
41
+ export type CoreBehavior = 'Draggable' | 'Toggleable';
42
+
43
+ /**
44
+ * Common tier behaviors (high usage).
45
+ */
46
+ export type CommonBehavior = 'Sortable' | 'Removable';
47
+
48
+ /**
49
+ * Optional tier behaviors (load on demand).
50
+ */
51
+ export type OptionalBehavior = 'Resizable';
@@ -0,0 +1,180 @@
1
+ import { describe, it, expect } from 'vitest';
2
+ import {
3
+ // Individual behavior exports
4
+ draggableSource,
5
+ draggableMetadata,
6
+ removableSource,
7
+ removableMetadata,
8
+ toggleableSource,
9
+ toggleableMetadata,
10
+ sortableSource,
11
+ sortableMetadata,
12
+ resizableSource,
13
+ resizableMetadata,
14
+ // Registry functions
15
+ getAvailableBehaviors,
16
+ getBehaviorsByCategory,
17
+ getBehaviorsByTier,
18
+ getAllSchemas,
19
+ // Registration functions
20
+ registerDraggable,
21
+ registerRemovable,
22
+ registerToggleable,
23
+ registerSortable,
24
+ registerResizable,
25
+ registerAll,
26
+ } from './index';
27
+
28
+ describe('@hyperfixi/behaviors', () => {
29
+ describe('exports', () => {
30
+ it('should export all behavior sources', () => {
31
+ expect(draggableSource).toBeDefined();
32
+ expect(removableSource).toBeDefined();
33
+ expect(toggleableSource).toBeDefined();
34
+ expect(sortableSource).toBeDefined();
35
+ expect(resizableSource).toBeDefined();
36
+ });
37
+
38
+ it('should export all behavior metadata', () => {
39
+ expect(draggableMetadata.name).toBe('Draggable');
40
+ expect(removableMetadata.name).toBe('Removable');
41
+ expect(toggleableMetadata.name).toBe('Toggleable');
42
+ expect(sortableMetadata.name).toBe('Sortable');
43
+ expect(resizableMetadata.name).toBe('Resizable');
44
+ });
45
+
46
+ it('should export register functions', () => {
47
+ expect(registerDraggable).toBeDefined();
48
+ expect(registerRemovable).toBeDefined();
49
+ expect(registerToggleable).toBeDefined();
50
+ expect(registerSortable).toBeDefined();
51
+ expect(registerResizable).toBeDefined();
52
+ expect(registerAll).toBeDefined();
53
+ });
54
+ });
55
+
56
+ describe('registry', () => {
57
+ it('getAvailableBehaviors should return all behavior names', () => {
58
+ const names = getAvailableBehaviors();
59
+ expect(names).toContain('Draggable');
60
+ expect(names).toContain('Removable');
61
+ expect(names).toContain('Toggleable');
62
+ expect(names).toContain('Sortable');
63
+ expect(names).toContain('Resizable');
64
+ expect(names.length).toBe(5);
65
+ });
66
+
67
+ it('getBehaviorsByCategory should group by category', () => {
68
+ expect(getBehaviorsByCategory('ui')).toEqual(['Draggable', 'Sortable', 'Resizable']);
69
+ expect(getBehaviorsByCategory('data')).toEqual(['Removable']);
70
+ expect(getBehaviorsByCategory('form')).toEqual(['Toggleable']);
71
+ });
72
+
73
+ it('getBehaviorsByTier should group by tier', () => {
74
+ expect(getBehaviorsByTier('core')).toEqual(['Draggable', 'Toggleable']);
75
+ expect(getBehaviorsByTier('common')).toEqual(['Sortable', 'Removable']);
76
+ expect(getBehaviorsByTier('optional')).toEqual(['Resizable']);
77
+ });
78
+
79
+ it('getAllSchemas should return all schemas', () => {
80
+ const schemas = getAllSchemas();
81
+ expect(schemas.length).toBe(5);
82
+ expect(schemas.map(s => s.name).sort()).toEqual([
83
+ 'Draggable',
84
+ 'Removable',
85
+ 'Resizable',
86
+ 'Sortable',
87
+ 'Toggleable',
88
+ ]);
89
+ });
90
+ });
91
+
92
+ describe('Draggable behavior', () => {
93
+ it('should have valid hyperscript source', () => {
94
+ expect(draggableSource).toContain('behavior Draggable');
95
+ expect(draggableSource).toContain('on pointerdown');
96
+ expect(draggableSource).toContain('trigger draggable:start');
97
+ });
98
+
99
+ it('should have correct schema metadata', () => {
100
+ expect(draggableMetadata.category).toBe('ui');
101
+ expect(draggableMetadata.tier).toBe('core');
102
+ expect(draggableMetadata.parameters).toBeDefined();
103
+ expect(draggableMetadata.parameters?.length).toBeGreaterThan(0);
104
+ });
105
+
106
+ it('should document events', () => {
107
+ expect(draggableMetadata.events).toBeDefined();
108
+ expect(draggableMetadata.events?.map(e => e.name)).toContain('draggable:start');
109
+ expect(draggableMetadata.events?.map(e => e.name)).toContain('draggable:end');
110
+ });
111
+ });
112
+
113
+ describe('Removable behavior', () => {
114
+ it('should have valid hyperscript source', () => {
115
+ expect(removableSource).toContain('behavior Removable');
116
+ expect(removableSource).toContain('on click');
117
+ expect(removableSource).toContain('remove me');
118
+ });
119
+
120
+ it('should have correct schema metadata', () => {
121
+ expect(removableMetadata.category).toBe('data');
122
+ expect(removableMetadata.tier).toBe('common');
123
+ });
124
+
125
+ it('should support confirmation parameter', () => {
126
+ expect(removableSource).toContain('if confirm');
127
+ });
128
+
129
+ it('should use triggerEl parameter (not trigger)', () => {
130
+ expect(removableSource).toContain('behavior Removable(triggerEl');
131
+ expect(removableSource).toContain('on click from triggerEl');
132
+ });
133
+ });
134
+
135
+ describe('Toggleable behavior', () => {
136
+ it('should have valid hyperscript source', () => {
137
+ expect(toggleableSource).toContain('behavior Toggleable');
138
+ expect(toggleableSource).toContain('on click');
139
+ });
140
+
141
+ it('should have correct schema metadata', () => {
142
+ expect(toggleableMetadata.category).toBe('form');
143
+ expect(toggleableMetadata.tier).toBe('core');
144
+ });
145
+
146
+ it('should default to "active" class', () => {
147
+ expect(toggleableSource).toContain('set cls to "active"');
148
+ });
149
+ });
150
+
151
+ describe('Sortable behavior', () => {
152
+ it('should have valid hyperscript source', () => {
153
+ expect(sortableSource).toContain('behavior Sortable');
154
+ expect(sortableSource).toContain('on pointerdown');
155
+ expect(sortableSource).toContain('trigger sortable:');
156
+ });
157
+
158
+ it('should have correct schema metadata', () => {
159
+ expect(sortableMetadata.category).toBe('ui');
160
+ expect(sortableMetadata.tier).toBe('common');
161
+ });
162
+ });
163
+
164
+ describe('Resizable behavior', () => {
165
+ it('should have valid hyperscript source', () => {
166
+ expect(resizableSource).toContain('behavior Resizable');
167
+ expect(resizableSource).toContain('on pointerdown');
168
+ });
169
+
170
+ it('should have correct schema metadata', () => {
171
+ expect(resizableMetadata.category).toBe('ui');
172
+ expect(resizableMetadata.tier).toBe('optional');
173
+ });
174
+
175
+ it('should support min/max constraints', () => {
176
+ expect(resizableSource).toContain('minWidth');
177
+ expect(resizableSource).toContain('maxWidth');
178
+ });
179
+ });
180
+ });
package/src/index.ts ADDED
@@ -0,0 +1,222 @@
1
+ /**
2
+ * @hyperfixi/behaviors
3
+ *
4
+ * Reusable hyperscript behaviors for LokaScript.
5
+ * Each behavior can be imported individually for tree-shaking,
6
+ * or all behaviors can be registered at once.
7
+ *
8
+ * @example Individual import (tree-shakeable)
9
+ * ```javascript
10
+ * import { registerDraggable } from '@hyperfixi/behaviors/draggable';
11
+ * await registerDraggable();
12
+ * ```
13
+ *
14
+ * @example Import all
15
+ * ```javascript
16
+ * import { registerAll } from '@hyperfixi/behaviors';
17
+ * await registerAll();
18
+ * ```
19
+ *
20
+ * @example Registry-based lazy loading
21
+ * ```javascript
22
+ * import { loadBehavior, getBehaviorsByCategory } from '@hyperfixi/behaviors';
23
+ * await loadBehavior('Draggable');
24
+ * const uiBehaviors = getBehaviorsByCategory('ui');
25
+ * ```
26
+ *
27
+ * @example CDN usage
28
+ * ```html
29
+ * <script src="lokascript-browser.js"></script>
30
+ * <script src="@hyperfixi/behaviors/draggable.browser.js"></script>
31
+ * <!-- Draggable is auto-registered -->
32
+ * ```
33
+ */
34
+
35
+ // =============================================================================
36
+ // Re-export individual behaviors
37
+ // =============================================================================
38
+
39
+ export {
40
+ draggableSource,
41
+ draggableMetadata,
42
+ registerDraggable,
43
+ default as Draggable,
44
+ } from './behaviors/draggable';
45
+
46
+ export {
47
+ removableSource,
48
+ removableMetadata,
49
+ registerRemovable,
50
+ default as Removable,
51
+ } from './behaviors/removable';
52
+
53
+ export {
54
+ toggleableSource,
55
+ toggleableMetadata,
56
+ registerToggleable,
57
+ default as Toggleable,
58
+ } from './behaviors/toggleable';
59
+
60
+ export {
61
+ sortableSource,
62
+ sortableMetadata,
63
+ registerSortable,
64
+ default as Sortable,
65
+ } from './behaviors/sortable';
66
+
67
+ export {
68
+ resizableSource,
69
+ resizableMetadata,
70
+ registerResizable,
71
+ default as Resizable,
72
+ } from './behaviors/resizable';
73
+
74
+ // =============================================================================
75
+ // Types
76
+ // =============================================================================
77
+
78
+ export type {
79
+ BehaviorSchema,
80
+ BehaviorCategory,
81
+ BehaviorTier,
82
+ ParameterSchema,
83
+ EventSchema,
84
+ BehaviorModule,
85
+ LokaScriptInstance,
86
+ } from './schemas/types';
87
+
88
+ // =============================================================================
89
+ // Initialize registry with loaders (populates schemas and loaders)
90
+ // =============================================================================
91
+
92
+ import './loaders';
93
+
94
+ // =============================================================================
95
+ // Registry exports
96
+ // =============================================================================
97
+
98
+ export {
99
+ // Registration
100
+ registerBehavior,
101
+ registerSchema,
102
+ registerLoader,
103
+ // Query (sync)
104
+ getBehavior,
105
+ tryGetBehavior,
106
+ getSchema,
107
+ tryGetSchema,
108
+ isRegistered,
109
+ hasLoader,
110
+ getRegisteredBehaviors,
111
+ getAvailableBehaviors,
112
+ // Query by metadata
113
+ getBehaviorsByCategory,
114
+ getBehaviorsByTier,
115
+ getAllSchemas,
116
+ getAllSchemasRecord,
117
+ // Lazy loading (async)
118
+ loadBehavior,
119
+ preloadTier,
120
+ preloadCategory,
121
+ loadAll,
122
+ // Runtime registration
123
+ registerWithRuntime,
124
+ registerAllWithRuntime,
125
+ } from './registry';
126
+
127
+ // =============================================================================
128
+ // Generated types and metadata
129
+ // =============================================================================
130
+
131
+ export type {
132
+ BehaviorName,
133
+ UIBehavior,
134
+ DataBehavior,
135
+ AnimationBehavior,
136
+ FormBehavior,
137
+ LayoutBehavior,
138
+ CoreBehavior,
139
+ CommonBehavior,
140
+ OptionalBehavior,
141
+ } from './generated/types';
142
+
143
+ export {
144
+ ALL_BEHAVIOR_NAMES,
145
+ BEHAVIORS_BY_CATEGORY,
146
+ BEHAVIORS_BY_TIER,
147
+ BEHAVIOR_CATEGORIES,
148
+ BEHAVIOR_TIERS,
149
+ } from './generated/metadata';
150
+
151
+ // =============================================================================
152
+ // Convenience functions
153
+ // =============================================================================
154
+
155
+ import { registerDraggable } from './behaviors/draggable';
156
+ import { registerRemovable } from './behaviors/removable';
157
+ import { registerToggleable } from './behaviors/toggleable';
158
+ import { registerSortable } from './behaviors/sortable';
159
+ import { registerResizable } from './behaviors/resizable';
160
+ import type { LokaScriptInstance, LokaScriptWindow } from './schemas/types';
161
+
162
+ /**
163
+ * Register all behaviors with HyperFixi.
164
+ *
165
+ * @param hyperfixi - The hyperfixi instance (defaults to window.hyperfixi)
166
+ * @returns Promise that resolves when all behaviors are registered
167
+ *
168
+ * @example
169
+ * ```javascript
170
+ * import { registerAll } from '@hyperfixi/behaviors';
171
+ * await registerAll();
172
+ * ```
173
+ */
174
+ export async function registerAll(hyperfixi?: LokaScriptInstance): Promise<void> {
175
+ await Promise.all([
176
+ registerDraggable(hyperfixi),
177
+ registerRemovable(hyperfixi),
178
+ registerToggleable(hyperfixi),
179
+ registerSortable(hyperfixi),
180
+ registerResizable(hyperfixi),
181
+ ]);
182
+ }
183
+
184
+ // =============================================================================
185
+ // Auto-registration for browser
186
+ // =============================================================================
187
+
188
+ /**
189
+ * Promise that resolves when all behaviors are registered.
190
+ * This is set when the package auto-registers in browser environments.
191
+ */
192
+ export let ready: Promise<void> | null = null;
193
+
194
+ // Auto-register all behaviors when loaded in browser with hyperfixi available
195
+ if (typeof window !== 'undefined' && (window as unknown as LokaScriptWindow).lokascript) {
196
+ const lsWin = window as unknown as LokaScriptWindow;
197
+ ready = registerAll();
198
+
199
+ lsWin.__lokascript_behaviors_ready = ready;
200
+
201
+ ready
202
+ .then(() => {
203
+ const hyperfixi = lsWin.lokascript as LokaScriptInstance & {
204
+ attributeProcessor?: { scanAndProcessAll: () => Promise<void> };
205
+ processNode?: (node: Document) => void;
206
+ };
207
+ const savedPromise = lsWin.__lokascript_behaviors_ready;
208
+ delete lsWin.__lokascript_behaviors_ready;
209
+
210
+ if (hyperfixi.attributeProcessor?.scanAndProcessAll) {
211
+ hyperfixi.attributeProcessor.scanAndProcessAll().finally(() => {
212
+ lsWin.__lokascript_behaviors_ready = savedPromise;
213
+ });
214
+ } else if (hyperfixi.processNode) {
215
+ hyperfixi.processNode(document);
216
+ lsWin.__lokascript_behaviors_ready = savedPromise;
217
+ }
218
+ })
219
+ .catch(err => {
220
+ console.error('[behaviors] Auto-registration failed:', err);
221
+ });
222
+ }
package/src/loaders.ts ADDED
@@ -0,0 +1,39 @@
1
+ /**
2
+ * Behavior Loaders
3
+ *
4
+ * Registers lazy loaders for all behaviors.
5
+ * Import this module to enable on-demand loading without bundling all behaviors.
6
+ *
7
+ * @example
8
+ * ```typescript
9
+ * // Enable lazy loading
10
+ * import '@hyperfixi/behaviors/loaders';
11
+ *
12
+ * // Now load behaviors on demand
13
+ * import { loadBehavior } from '@hyperfixi/behaviors/registry';
14
+ * await loadBehavior('Draggable');
15
+ * ```
16
+ */
17
+
18
+ import { registerLoader, registerSchema } from './registry';
19
+
20
+ // Register schemas for metadata queries before loading
21
+ import { draggableSchema } from './schemas/draggable.schema';
22
+ import { sortableSchema } from './schemas/sortable.schema';
23
+ import { resizableSchema } from './schemas/resizable.schema';
24
+ import { removableSchema } from './schemas/removable.schema';
25
+ import { toggleableSchema } from './schemas/toggleable.schema';
26
+
27
+ // Register all schemas
28
+ registerSchema(draggableSchema);
29
+ registerSchema(sortableSchema);
30
+ registerSchema(resizableSchema);
31
+ registerSchema(removableSchema);
32
+ registerSchema(toggleableSchema);
33
+
34
+ // Register lazy loaders - behaviors are only loaded when requested
35
+ registerLoader('Draggable', () => import('./behaviors/draggable'));
36
+ registerLoader('Sortable', () => import('./behaviors/sortable'));
37
+ registerLoader('Resizable', () => import('./behaviors/resizable'));
38
+ registerLoader('Removable', () => import('./behaviors/removable'));
39
+ registerLoader('Toggleable', () => import('./behaviors/toggleable'));