@jqhtml/core 2.2.222

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 (46) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +24 -0
  3. package/dist/component-registry.d.ts +64 -0
  4. package/dist/component-registry.d.ts.map +1 -0
  5. package/dist/component.d.ts +336 -0
  6. package/dist/component.d.ts.map +1 -0
  7. package/dist/debug-entry.d.ts +36 -0
  8. package/dist/debug-entry.d.ts.map +1 -0
  9. package/dist/debug-overlay.d.ts +61 -0
  10. package/dist/debug-overlay.d.ts.map +1 -0
  11. package/dist/debug.d.ts +19 -0
  12. package/dist/debug.d.ts.map +1 -0
  13. package/dist/index.cjs +4384 -0
  14. package/dist/index.cjs.map +1 -0
  15. package/dist/index.d.ts +91 -0
  16. package/dist/index.d.ts.map +1 -0
  17. package/dist/index.js +4347 -0
  18. package/dist/index.js.map +1 -0
  19. package/dist/instruction-processor.d.ts +31 -0
  20. package/dist/instruction-processor.d.ts.map +1 -0
  21. package/dist/jqhtml-core.esm.js +4352 -0
  22. package/dist/jqhtml-core.esm.js.map +1 -0
  23. package/dist/jqhtml-debug.esm.js +575 -0
  24. package/dist/jqhtml-debug.esm.js.map +1 -0
  25. package/dist/jquery-plugin.d.ts +30 -0
  26. package/dist/jquery-plugin.d.ts.map +1 -0
  27. package/dist/lifecycle-manager.d.ts +34 -0
  28. package/dist/lifecycle-manager.d.ts.map +1 -0
  29. package/dist/load-coordinator.d.ts +79 -0
  30. package/dist/load-coordinator.d.ts.map +1 -0
  31. package/dist/local-storage.d.ts +147 -0
  32. package/dist/local-storage.d.ts.map +1 -0
  33. package/dist/template-renderer.d.ts +17 -0
  34. package/dist/template-renderer.d.ts.map +1 -0
  35. package/laravel-bridge/README.md +242 -0
  36. package/laravel-bridge/autoload.php +51 -0
  37. package/laravel-bridge/composer.json +34 -0
  38. package/laravel-bridge/config/jqhtml.php +82 -0
  39. package/laravel-bridge/examples/node-integration.js +201 -0
  40. package/laravel-bridge/src/JqhtmlErrorFormatter.php +187 -0
  41. package/laravel-bridge/src/JqhtmlException.php +173 -0
  42. package/laravel-bridge/src/JqhtmlExceptionRenderer.php +93 -0
  43. package/laravel-bridge/src/JqhtmlServiceProvider.php +72 -0
  44. package/laravel-bridge/src/Middleware/JqhtmlErrorMiddleware.php +90 -0
  45. package/laravel-bridge/tests/ExceptionFormattingTest.php +219 -0
  46. package/package.json +74 -0
@@ -0,0 +1,79 @@
1
+ /**
2
+ * Load Coordinator - Request deduplication for component on_load() calls
3
+ *
4
+ * Coordinates parallel component loading to prevent duplicate requests.
5
+ * When multiple components with identical names and args load simultaneously,
6
+ * only the first (leader) executes on_load(). Others (followers) wait for
7
+ * the leader's result.
8
+ *
9
+ * Key Concepts:
10
+ * - **INVOCATION_KEY**: Unique identifier for component name + args combination
11
+ * - **Leader**: First component to reach on_load() for a given INVOCATION_KEY
12
+ * - **Follower**: Subsequent components that wait for leader's result
13
+ *
14
+ * Lifecycle:
15
+ * 1. Leader reaches on_load() → create coordination entry
16
+ * 2. Followers reach on_load() → join waiting queue
17
+ * 3. Leader completes → distribute data to all followers
18
+ * 4. Clear coordination entry (no caching)
19
+ *
20
+ * @internal This class is not exposed in the public API
21
+ */
22
+ import type { Jqhtml_Component } from './component.js';
23
+ export interface InvocationKeyResult {
24
+ key: string | null;
25
+ uncacheable_property?: string;
26
+ }
27
+ export declare class Load_Coordinator {
28
+ private static _registry;
29
+ /**
30
+ * Generate INVOCATION_KEY from component name and args
31
+ * Uses deterministic JSON serialization (sorted keys)
32
+ * Excludes internal properties (those starting with _)
33
+ *
34
+ * For functions/objects:
35
+ * - Checks for ._jqhtml_cache_id property (assigned by RSpade)
36
+ * - Falls back to .jqhtml_cache_id() method if property doesn't exist
37
+ * - If neither exists, marks property as uncacheable
38
+ *
39
+ * Returns object with:
40
+ * - key: Cache key string, or null if uncacheable
41
+ * - uncacheable_property: Name of first property that prevented caching (for debugging)
42
+ */
43
+ static generate_invocation_key(component_name: string, args: any): InvocationKeyResult;
44
+ /**
45
+ * Check if a component should execute on_load() or wait for existing request
46
+ * Returns true if component should execute (is leader), false if should wait (is follower)
47
+ */
48
+ static should_execute_on_load(component: Jqhtml_Component): boolean;
49
+ /**
50
+ * Register a leader component that will execute on_load()
51
+ * Creates coordination entry and returns a function to call when on_load() completes
52
+ */
53
+ static register_leader(component: Jqhtml_Component, on_load_promise: Promise<void>): () => void;
54
+ /**
55
+ * Get the coordination promise for a follower component
56
+ * Returns a promise that resolves when the leader completes
57
+ */
58
+ static get_coordination_promise(component: Jqhtml_Component): Promise<void> | null;
59
+ /**
60
+ * Complete coordination after leader's on_load() finishes
61
+ * Distributes data to all waiting followers and cleans up entry
62
+ * @private
63
+ */
64
+ private static _complete_coordination;
65
+ /**
66
+ * Handle leader on_load() error
67
+ * Propagates error to all followers and cleans up entry
68
+ */
69
+ static handle_leader_error(component: Jqhtml_Component, error: Error): void;
70
+ /**
71
+ * Get current registry state (for debugging)
72
+ */
73
+ static get_registry_state(): any;
74
+ /**
75
+ * Clear all coordination entries (for testing/debugging)
76
+ */
77
+ static clear_all(): void;
78
+ }
79
+ //# sourceMappingURL=load-coordinator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"load-coordinator.d.ts","sourceRoot":"","sources":["../src/load-coordinator.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAWvD,MAAM,WAAW,mBAAmB;IAChC,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;IACnB,oBAAoB,CAAC,EAAE,MAAM,CAAC;CACjC;AAED,qBAAa,gBAAgB;IACzB,OAAO,CAAC,MAAM,CAAC,SAAS,CAA6C;IAErE;;;;;;;;;;;;;OAaG;IACH,MAAM,CAAC,uBAAuB,CAAC,cAAc,EAAE,MAAM,EAAE,IAAI,EAAE,GAAG,GAAG,mBAAmB;IAqEtF;;;OAGG;IACH,MAAM,CAAC,sBAAsB,CAAC,SAAS,EAAE,gBAAgB,GAAG,OAAO;IAoBnE;;;OAGG;IACH,MAAM,CAAC,eAAe,CAClB,SAAS,EAAE,gBAAgB,EAC3B,eAAe,EAAE,OAAO,CAAC,IAAI,CAAC,GAC/B,MAAM,IAAI;IAkBb;;;OAGG;IACH,MAAM,CAAC,wBAAwB,CAAC,SAAS,EAAE,gBAAgB,GAAG,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI;IAWlF;;;;OAIG;IACH,OAAO,CAAC,MAAM,CAAC,sBAAsB;IA8CrC;;;OAGG;IACH,MAAM,CAAC,mBAAmB,CAAC,SAAS,EAAE,gBAAgB,EAAE,KAAK,EAAE,KAAK,GAAG,IAAI;IAuC3E;;OAEG;IACH,MAAM,CAAC,kBAAkB,IAAI,GAAG;IAahC;;OAEG;IACH,MAAM,CAAC,SAAS,IAAI,IAAI;CAG3B"}
@@ -0,0 +1,147 @@
1
+ /**
2
+ * Jqhtml_Local_Storage - Scoped local storage for JQHTML component caching
3
+ *
4
+ * Provides safe, scoped access to localStorage with automatic handling of
5
+ * unavailable storage, quota exceeded errors, and scope invalidation.
6
+ *
7
+ * Key Features:
8
+ * - **Manual scoping**: Cache key must be set via set_cache_key() before use
9
+ * - **Graceful degradation**: Returns null when storage unavailable or cache key not set
10
+ * - **Quota management**: Auto-clears storage when full and retries operation
11
+ * - **Scope validation**: Clears storage when cache key changes
12
+ * - **Developer-friendly keys**: Scoped suffix allows easy inspection in dev tools
13
+ *
14
+ * Scoping Strategy:
15
+ * Storage is scoped by a user-provided cache key (typically a session identifier,
16
+ * user ID, or combination of relevant scope factors). This scope is stored in
17
+ * `_jqhtml_cache_key`. If the cache key changes between page loads, all JQHTML
18
+ * storage is cleared to prevent stale data from different sessions/users.
19
+ *
20
+ * Key Format:
21
+ * Keys are stored as: `jqhtml::developer_key::cache_key`
22
+ * Example: `jqhtml::User_Profile_data::user_123`
23
+ *
24
+ * The `jqhtml::` prefix identifies JQHTML keys, allowing safe clearing of only our keys
25
+ * without affecting other JavaScript libraries. This enables transparent coexistence
26
+ * with third-party libraries that also use browser storage.
27
+ *
28
+ * Quota Exceeded Handling:
29
+ * When storage quota is exceeded during a set operation, only JQHTML keys (prefixed with
30
+ * `jqhtml::`) are cleared, preserving other libraries' data. The operation is then retried
31
+ * once. This ensures the application continues functioning even when storage is full.
32
+ *
33
+ * Usage:
34
+ * // Must set cache key first (typically done once on page load)
35
+ * Jqhtml_Local_Storage.set_cache_key('user_123');
36
+ *
37
+ * // Then use storage normally
38
+ * Jqhtml_Local_Storage.set('cached_component', {html: '...', timestamp: Date.now()});
39
+ * const cached = Jqhtml_Local_Storage.get('cached_component');
40
+ * Jqhtml_Local_Storage.remove('cached_component');
41
+ *
42
+ * IMPORTANT - Volatile Storage:
43
+ * Storage can be cleared at any time due to:
44
+ * - User clearing browser data
45
+ * - Private browsing mode restrictions
46
+ * - Quota exceeded errors
47
+ * - Cache key changes
48
+ * - Browser storage unavailable
49
+ *
50
+ * Therefore, NEVER store critical data. Only use for:
51
+ * - Cached component HTML (performance optimization)
52
+ * - Transient UI state (convenience, not required)
53
+ *
54
+ * @internal This class is not exposed in the public API
55
+ */
56
+ export declare class Jqhtml_Local_Storage {
57
+ private static _cache_key;
58
+ private static _storage_available;
59
+ private static _initialized;
60
+ /**
61
+ * Set the cache key and initialize storage
62
+ * Must be called before any get/set operations
63
+ * @param {string} cache_key - Unique identifier for this cache scope
64
+ */
65
+ static set_cache_key(cache_key: string): void;
66
+ /**
67
+ * Check if cache key has been set
68
+ * @returns {boolean} True if cache key is configured
69
+ */
70
+ static has_cache_key(): boolean;
71
+ /**
72
+ * Initialize storage system and validate scope
73
+ * Called automatically after cache key is set
74
+ * @private
75
+ */
76
+ private static _init;
77
+ /**
78
+ * Check if localStorage is available
79
+ * @returns {boolean}
80
+ * @private
81
+ */
82
+ private static _is_storage_available;
83
+ /**
84
+ * Validate storage scope and clear JQHTML keys if cache key changed
85
+ * Only clears keys prefixed with 'jqhtml::' to preserve other libraries' data
86
+ * @private
87
+ */
88
+ private static _validate_scope;
89
+ /**
90
+ * Clear only JQHTML keys from storage (keys starting with 'jqhtml::')
91
+ * Preserves keys from other libraries
92
+ * @private
93
+ */
94
+ private static _clear_jqhtml_keys;
95
+ /**
96
+ * Build scoped key with JQHTML namespace prefix
97
+ * @param {string} key - Developer-provided key
98
+ * @returns {string}
99
+ * @private
100
+ */
101
+ private static _build_key;
102
+ /**
103
+ * Check if storage is ready for use
104
+ * @returns {boolean}
105
+ * @private
106
+ */
107
+ private static _is_ready;
108
+ /**
109
+ * Set item in localStorage
110
+ * @param {string} key - Storage key
111
+ * @param {*} value - Value to store (will be JSON serialized)
112
+ */
113
+ static set(key: string, value: any): void;
114
+ /**
115
+ * Get item from localStorage
116
+ * @param {string} key - Storage key
117
+ * @returns {*|null} Parsed value or null if not found/unavailable
118
+ */
119
+ static get(key: string): any | null;
120
+ /**
121
+ * Remove item from localStorage
122
+ * @param {string} key - Storage key
123
+ */
124
+ static remove(key: string): void;
125
+ /**
126
+ * Internal set implementation with scope validation and quota handling
127
+ * @param {string} key
128
+ * @param {*} value - Original value (not used, kept for clarity)
129
+ * @param {string} serialized - Pre-serialized JSON string
130
+ * @private
131
+ */
132
+ private static _set_item;
133
+ /**
134
+ * Internal get implementation
135
+ * @param {string} key
136
+ * @returns {*|null}
137
+ * @private
138
+ */
139
+ private static _get_item;
140
+ /**
141
+ * Internal remove implementation
142
+ * @param {string} key
143
+ * @private
144
+ */
145
+ private static _remove_item;
146
+ }
147
+ //# sourceMappingURL=local-storage.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"local-storage.d.ts","sourceRoot":"","sources":["../src/local-storage.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsDG;AACH,qBAAa,oBAAoB;IAC7B,OAAO,CAAC,MAAM,CAAC,UAAU,CAAuB;IAChD,OAAO,CAAC,MAAM,CAAC,kBAAkB,CAAwB;IACzD,OAAO,CAAC,MAAM,CAAC,YAAY,CAAkB;IAE7C;;;;OAIG;IACH,MAAM,CAAC,aAAa,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI;IAK7C;;;OAGG;IACH,MAAM,CAAC,aAAa,IAAI,OAAO;IAI/B;;;;OAIG;IACH,OAAO,CAAC,MAAM,CAAC,KAAK;IAepB;;;;OAIG;IACH,OAAO,CAAC,MAAM,CAAC,qBAAqB;IAYpC;;;;OAIG;IACH,OAAO,CAAC,MAAM,CAAC,eAAe;IA4B9B;;;;OAIG;IACH,OAAO,CAAC,MAAM,CAAC,kBAAkB;IA2BjC;;;;;OAKG;IACH,OAAO,CAAC,MAAM,CAAC,UAAU;IAIzB;;;;OAIG;IACH,OAAO,CAAC,MAAM,CAAC,SAAS;IAIxB;;;;OAIG;IACH,MAAM,CAAC,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,GAAG,IAAI;IAqBzC;;;;OAIG;IACH,MAAM,CAAC,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,GAAG,IAAI;IAQnC;;;OAGG;IACH,MAAM,CAAC,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI;IAQhC;;;;;;OAMG;IACH,OAAO,CAAC,MAAM,CAAC,SAAS;IA4BxB;;;;;OAKG;IACH,OAAO,CAAC,MAAM,CAAC,SAAS;IAexB;;;;OAIG;IACH,OAAO,CAAC,MAAM,CAAC,YAAY;CAS9B"}
@@ -0,0 +1,17 @@
1
+ /**
2
+ * JQHTML v2 Template Renderer
3
+ *
4
+ * Connects compiled templates to components
5
+ * Processes instruction arrays and handles bindings
6
+ */
7
+ import type { Jqhtml_Component } from './component.js';
8
+ /**
9
+ * Render a template for a component
10
+ * Templates are functions that return [instructions, context] tuples
11
+ */
12
+ export declare function render_template(component: Jqhtml_Component, template_fn?: Function): Promise<void>;
13
+ /**
14
+ * Helper to escape HTML for safe output
15
+ */
16
+ export declare function escape_html(str: string): string;
17
+ //# sourceMappingURL=template-renderer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"template-renderer.d.ts","sourceRoot":"","sources":["../src/template-renderer.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AA2EvD;;;GAGG;AACH,wBAAsB,eAAe,CACnC,SAAS,EAAE,gBAAgB,EAC3B,WAAW,CAAC,EAAE,QAAQ,GACrB,OAAO,CAAC,IAAI,CAAC,CAqDf;AA6KD;;GAEG;AACH,wBAAgB,WAAW,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAI/C"}
@@ -0,0 +1,242 @@
1
+ # JQHTML Laravel Bridge
2
+
3
+ Laravel integration package for JQHTML template error reporting with source map support.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ composer require jqhtml/laravel-bridge
9
+ ```
10
+
11
+ ## Configuration
12
+
13
+ Publish the configuration file:
14
+
15
+ ```bash
16
+ php artisan vendor:publish --tag=jqhtml-config
17
+ ```
18
+
19
+ ## Usage
20
+
21
+ ### Basic Setup
22
+
23
+ The package automatically registers its service provider and exception handler extensions. No additional setup is required for basic functionality.
24
+
25
+ ### Error Handling
26
+
27
+ When a JQHTML template error occurs, the package will:
28
+
29
+ 1. Parse the error message to extract template location information
30
+ 2. Load source maps if available
31
+ 3. Format the error for Laravel's exception handler
32
+ 4. Display enhanced error information in debug mode
33
+
34
+ ### Middleware
35
+
36
+ To automatically catch and format JQHTML errors, add the middleware to your route groups:
37
+
38
+ ```php
39
+ // In app/Http/Kernel.php
40
+ protected $middlewareGroups = [
41
+ 'web' => [
42
+ // ...
43
+ \Jqhtml\LaravelBridge\Middleware\JqhtmlErrorMiddleware::class,
44
+ ],
45
+ ];
46
+ ```
47
+
48
+ ### Manual Exception Creation
49
+
50
+ ```php
51
+ use Jqhtml\LaravelBridge\JqhtmlException;
52
+
53
+ // Create from JavaScript error data
54
+ $jsError = json_decode($errorJson, true);
55
+ $exception = JqhtmlException::createFromJsError($jsError);
56
+
57
+ // Create manually
58
+ $exception = new JqhtmlException(
59
+ 'Unclosed component definition',
60
+ 'templates/user-card.jqhtml', // template file
61
+ 42, // line number
62
+ 15, // column number
63
+ $sourceCode, // template source
64
+ 'Did you forget </Define:UserCard>?' // suggestion
65
+ );
66
+ ```
67
+
68
+ ### Integration with Node.js Compiler
69
+
70
+ When compiling JQHTML templates with Node.js, catch errors and pass them to Laravel:
71
+
72
+ ```javascript
73
+ // Node.js side
74
+ try {
75
+ const compiled = jqhtml.compile(template);
76
+ } catch (error) {
77
+ // Send error details to Laravel
78
+ const errorData = {
79
+ message: error.message,
80
+ filename: error.filename,
81
+ line: error.line,
82
+ column: error.column,
83
+ source: error.source,
84
+ suggestion: error.suggestion
85
+ };
86
+
87
+ // Pass to Laravel via API or process communication
88
+ sendToLaravel(errorData);
89
+ }
90
+ ```
91
+
92
+ ```php
93
+ // Laravel side - Best Practice
94
+ use Jqhtml\LaravelBridge\JqhtmlException;
95
+
96
+ // Parse compiler JSON output
97
+ $errorData = json_decode($compiler_output, true);
98
+
99
+ if ($errorData && isset($errorData['error'])) {
100
+ // JqhtmlException extends ViewException, so this will show
101
+ // the template file as the error source in Laravel/Ignition
102
+ $exception = JqhtmlException::createFromJsError(
103
+ $errorData['error'],
104
+ $templatePath // Pass the actual template path
105
+ );
106
+ throw $exception;
107
+ }
108
+
109
+ // Alternative: Direct ViewException usage (if not using the bridge)
110
+ if ($errorData && isset($errorData['error'])) {
111
+ $error = $errorData['error'];
112
+ $line = $error['line'] ?? 1;
113
+
114
+ throw new \Illuminate\View\ViewException(
115
+ $error['message'],
116
+ 0, // code
117
+ 1, // severity
118
+ $templatePath, // file
119
+ $line, // line
120
+ null // previous
121
+ );
122
+ }
123
+ ```
124
+
125
+ ### Source Map Support
126
+
127
+ The package supports source maps for mapping compiled JavaScript back to original JQHTML templates:
128
+
129
+ ```php
130
+ // Configure source map storage location
131
+ config(['jqhtml.source_maps_path' => storage_path('sourcemaps')]);
132
+
133
+ // The formatter will automatically look for source maps
134
+ // when an error includes a compiled file reference
135
+ $exception->setCompiledFile('/path/to/compiled.js');
136
+ ```
137
+
138
+ ### Custom Error Views
139
+
140
+ Create a custom error view at `resources/views/jqhtml/error.blade.php`:
141
+
142
+ ```blade
143
+ @extends('errors::layout')
144
+
145
+ @section('title', 'JQHTML Template Error')
146
+
147
+ @section('message')
148
+ <div class="jqhtml-error">
149
+ <h2>{{ $exception->getMessage() }}</h2>
150
+
151
+ @if($exception->getSuggestion())
152
+ <div class="suggestion">
153
+ 💡 {{ $exception->getSuggestion() }}
154
+ </div>
155
+ @endif
156
+
157
+ @if($exception->getTemplateFile())
158
+ <div class="location">
159
+ 📍 {{ $exception->getTemplateFile() }}:{{ $exception->getTemplateLine() }}:{{ $exception->getTemplateColumn() }}
160
+ </div>
161
+ @endif
162
+
163
+ @if(isset($error_data['source_context']))
164
+ <div class="source-context">
165
+ <pre><code>@foreach($error_data['source_context'] as $line)
166
+ @if($line['is_error_line'])<strong>> {{ $line['line_number'] }} | {{ $line['content'] }}
167
+ @if($line['error_column']){{ str_repeat(' ', $line['error_column'] + 8) }}{{ str_repeat('^', 20) }}@endif</strong>
168
+ @else {{ $line['line_number'] }} | {{ $line['content'] }}
169
+ @endif
170
+ @endforeach</code></pre>
171
+ </div>
172
+ @endif
173
+ </div>
174
+ @endsection
175
+ ```
176
+
177
+ ## Configuration Options
178
+
179
+ ```php
180
+ return [
181
+ // Where to store source map files
182
+ 'source_maps_path' => storage_path('jqhtml-sourcemaps'),
183
+
184
+ // Show source code context in errors
185
+ 'show_source_context' => env('APP_DEBUG', false),
186
+
187
+ // Lines of context to show
188
+ 'context_lines' => 5,
189
+
190
+ // Cache compiled templates
191
+ 'cache_compiled' => !env('APP_DEBUG', false),
192
+
193
+ // Where to store compiled templates
194
+ 'compiled_path' => storage_path('jqhtml-compiled'),
195
+
196
+ // Enable source map generation
197
+ 'enable_source_maps' => env('APP_DEBUG', false),
198
+
199
+ // Source map mode: 'inline', 'external', or 'both'
200
+ 'source_map_mode' => 'external',
201
+ ];
202
+ ```
203
+
204
+ ## Laravel Ignition Integration
205
+
206
+ The package automatically integrates with Laravel Ignition (if installed) to provide enhanced error display:
207
+
208
+ - Template file location with line and column numbers
209
+ - Source code context with error highlighting
210
+ - Helpful suggestions for common mistakes
211
+ - Source map resolution for compiled files
212
+
213
+ ## API Reference
214
+
215
+ ### JqhtmlException
216
+
217
+ Main exception class for JQHTML template errors. **Extends Laravel's `ViewException`** for optimal integration with Laravel's error handling and Ignition error pages.
218
+
219
+ When thrown, this exception ensures:
220
+ - The template file appears as the error source in Laravel/Ignition
221
+ - Line numbers point to the actual template location
222
+ - The error page shows your JQHTML template, not the PHP processor
223
+
224
+ ### JqhtmlErrorFormatter
225
+
226
+ Formats exceptions for display with source context and source map support.
227
+
228
+ ### JqhtmlExceptionRenderer
229
+
230
+ Renders exceptions for web and JSON responses.
231
+
232
+ ### JqhtmlServiceProvider
233
+
234
+ Registers services and extends Laravel's exception handler.
235
+
236
+ ### JqhtmlErrorMiddleware
237
+
238
+ Middleware for catching and wrapping JQHTML errors.
239
+
240
+ ## License
241
+
242
+ MIT
@@ -0,0 +1,51 @@
1
+ <?php
2
+
3
+ /**
4
+ * JQHTML Laravel Bridge Autoloader
5
+ *
6
+ * Include this file from your Laravel project to load the JQHTML error handling bridge:
7
+ *
8
+ * require_once base_path('node_modules/@jqhtml/core/laravel-bridge/autoload.php');
9
+ *
10
+ * Or if using in a service provider:
11
+ *
12
+ * require_once dirname(__DIR__, 3) . '/node_modules/@jqhtml/core/laravel-bridge/autoload.php';
13
+ */
14
+
15
+ // This is a Laravel bridge - it REQUIRES Laravel to function
16
+ if (!class_exists('Illuminate\\Support\\ServiceProvider')) {
17
+ throw new \RuntimeException(
18
+ 'JQHTML Laravel Bridge requires Laravel. ' .
19
+ 'This file should only be included from within a Laravel application.'
20
+ );
21
+ }
22
+
23
+ // Register the autoloader for JQHTML Laravel Bridge classes
24
+ spl_autoload_register(function ($class) {
25
+ // Check if the class is in the Jqhtml\LaravelBridge namespace
26
+ $prefix = 'Jqhtml\\LaravelBridge\\';
27
+ $len = strlen($prefix);
28
+
29
+ if (strncmp($prefix, $class, $len) !== 0) {
30
+ return;
31
+ }
32
+
33
+ // Get the relative class name
34
+ $relative_class = substr($class, $len);
35
+
36
+ // Replace namespace separators with directory separators
37
+ $file = __DIR__ . '/src/' . str_replace('\\', '/', $relative_class) . '.php';
38
+
39
+ // If the file exists, require it
40
+ if (file_exists($file)) {
41
+ require $file;
42
+ }
43
+ });
44
+
45
+ // Auto-register the service provider if in Laravel application context
46
+ if (function_exists('app') && app() instanceof \Illuminate\Foundation\Application) {
47
+ app()->register(\Jqhtml\LaravelBridge\JqhtmlServiceProvider::class);
48
+ }
49
+
50
+ // Return the namespace for convenience
51
+ return 'Jqhtml\\LaravelBridge';
@@ -0,0 +1,34 @@
1
+ {
2
+ "name": "jqhtml/laravel-bridge",
3
+ "description": "Laravel integration bridge for JQHTML template error reporting and source maps",
4
+ "type": "library",
5
+ "license": "MIT",
6
+ "authors": [
7
+ {
8
+ "name": "JQHTML Team"
9
+ }
10
+ ],
11
+ "require": {
12
+ "php": "^7.4|^8.0",
13
+ "illuminate/support": "^8.0|^9.0|^10.0|^11.0"
14
+ },
15
+ "autoload": {
16
+ "psr-4": {
17
+ "Jqhtml\\LaravelBridge\\": "src/"
18
+ }
19
+ },
20
+ "autoload-dev": {
21
+ "psr-4": {
22
+ "Jqhtml\\LaravelBridge\\Tests\\": "tests/"
23
+ }
24
+ },
25
+ "extra": {
26
+ "laravel": {
27
+ "providers": [
28
+ "Jqhtml\\LaravelBridge\\JqhtmlServiceProvider"
29
+ ]
30
+ }
31
+ },
32
+ "minimum-stability": "stable",
33
+ "prefer-stable": true
34
+ }
@@ -0,0 +1,82 @@
1
+ <?php
2
+
3
+ return [
4
+ /*
5
+ |--------------------------------------------------------------------------
6
+ | JQHTML Source Maps Path
7
+ |--------------------------------------------------------------------------
8
+ |
9
+ | This option defines where JQHTML source map files should be stored.
10
+ | Source maps help map compiled JavaScript back to original JQHTML templates
11
+ | for better error reporting and debugging.
12
+ |
13
+ */
14
+ 'source_maps_path' => storage_path('jqhtml-sourcemaps'),
15
+
16
+ /*
17
+ |--------------------------------------------------------------------------
18
+ | Show Source Context
19
+ |--------------------------------------------------------------------------
20
+ |
21
+ | When enabled, error messages will include the surrounding source code
22
+ | context to help identify the exact location and nature of the error.
23
+ |
24
+ */
25
+ 'show_source_context' => env('APP_DEBUG', false),
26
+
27
+ /*
28
+ |--------------------------------------------------------------------------
29
+ | Error Context Lines
30
+ |--------------------------------------------------------------------------
31
+ |
32
+ | Number of lines to show before and after the error line when displaying
33
+ | source context in error messages.
34
+ |
35
+ */
36
+ 'context_lines' => 5,
37
+
38
+ /*
39
+ |--------------------------------------------------------------------------
40
+ | Cache Compiled Templates
41
+ |--------------------------------------------------------------------------
42
+ |
43
+ | When enabled, compiled JQHTML templates will be cached to improve
44
+ | performance. Disable during development for immediate template updates.
45
+ |
46
+ */
47
+ 'cache_compiled' => env('JQHTML_CACHE', !env('APP_DEBUG', false)),
48
+
49
+ /*
50
+ |--------------------------------------------------------------------------
51
+ | Compiled Templates Path
52
+ |--------------------------------------------------------------------------
53
+ |
54
+ | Directory where compiled JQHTML templates should be stored.
55
+ |
56
+ */
57
+ 'compiled_path' => storage_path('jqhtml-compiled'),
58
+
59
+ /*
60
+ |--------------------------------------------------------------------------
61
+ | Enable Source Maps
62
+ |--------------------------------------------------------------------------
63
+ |
64
+ | Whether to generate source maps for compiled templates. Source maps
65
+ | increase compilation time slightly but provide better debugging.
66
+ |
67
+ */
68
+ 'enable_source_maps' => env('APP_DEBUG', false),
69
+
70
+ /*
71
+ |--------------------------------------------------------------------------
72
+ | Source Map Mode
73
+ |--------------------------------------------------------------------------
74
+ |
75
+ | How source maps should be generated:
76
+ | - 'inline': Embed source map directly in compiled file
77
+ | - 'external': Save source map as separate .map file
78
+ | - 'both': Generate both inline and external source maps
79
+ |
80
+ */
81
+ 'source_map_mode' => 'external',
82
+ ];