@hkdigital/lib-core 0.4.27 → 0.4.29

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/CLAUDE.md ADDED
@@ -0,0 +1,350 @@
1
+ # SvelteKit Library
2
+
3
+ ## Project Overview
4
+ This is a modern SvelteKit library built with Svelte 5 and Skeleton.dev v3 components. The project emphasizes accessibility, clean code standards, and modern JavaScript patterns.
5
+
6
+ ## Architecture & Structure
7
+ - **Framework**: SvelteKit with Svelte 5 runes
8
+ - **UI Components**: Skeleton.dev version 3
9
+ - **Package Manager**: PNPM
10
+ - **Language**: Modern JavaScript (ES6+), no TypeScript
11
+ - **Module System**: ES Modules only (import/export)
12
+
13
+ ## Key Technical Decisions
14
+ - Uses Svelte 5 runes (`$state()`, `$derived()`, `$effect()`, `$props()`) for state management
15
+ - Snippet syntax with `{@render children()}` instead of deprecated `<slot />`
16
+ - WCAG 2.1 Level AA accessibility compliance
17
+ - 80-character line limit with rare exceptions
18
+ - Two-space indentation
19
+ - Descriptive camelCase naming conventions
20
+
21
+ ## Component Patterns
22
+ - All components use `let { ... } = $props()` with JSDoc type annotations
23
+ - Props always include `classes` and `...attrs` for flexibility
24
+ - Event handlers use Svelte 5 syntax (`onclick`, `onchange`)
25
+ - Snippet props typed as `import('svelte').Snippet`
26
+ - Private methods use hash prefix (`#methodName`)
27
+
28
+ ## JavaScript Class Patterns
29
+ - Use modern ES private methods with hash prefix: `#methodName()` instead of `_methodName()`
30
+ - Private fields also use hash prefix: `#privateField`
31
+ - Apply this to all JavaScript classes, not just Svelte components
32
+ - Never use `@private` in JSDoc for methods that start with `#` - the hash already indicates privacy
33
+
34
+ ## Development Standards
35
+ - Readable code over concise code
36
+ - Explicit error handling with try/catch for async operations
37
+ - JSDoc comments for all functions and variables
38
+ - English for all documentation and comments
39
+ - No dollar signs in variable names (reserved for Svelte)
40
+
41
+ ### ESLint Rule Suppression
42
+ - Use specific rule suppression instead of blanket disables
43
+ - For unused variables in method signatures (e.g., base class methods to be overridden):
44
+ ```javascript
45
+ // eslint-disable-next-line no-unused-vars
46
+ async _configure(newConfig, oldConfig = null) {
47
+ // Override in subclass
48
+ }
49
+ ```
50
+
51
+ ## Documentation & Comment Style
52
+ - **80-character line limit** - strictly enforce for ALL code and documentation
53
+ - Applies to code lines, JSDoc comments, parameter descriptions, and all text
54
+ - Wrap long JSDoc descriptions across multiple lines
55
+ - Break long parameter lists and descriptions at 80 characters
56
+ - **JSDoc formatting conventions:**
57
+ - Blank line between description and first `@param`
58
+ - Blank line between last `@param` and `@returns`
59
+ - No blank lines between consecutive `@param` tags with short descriptions
60
+ - Add extra newlines between `@param` entries ONLY when they have multi-line descriptions for better readability
61
+ - For long parameter types or descriptions, place description on next line:
62
+ ```javascript
63
+ // Multi-line @param descriptions (use extra newlines between)
64
+ /**
65
+ * Convert a path string to an array path
66
+ *
67
+ * @param {string|string[]} path
68
+ * String or array path (e.g. "some.path.to")
69
+ *
70
+ * @param {string} [pathSeparator=PATH_SEPARATOR]
71
+ * A custom path separator to use instead of the default "."
72
+ *
73
+ * @returns {string[]} array path (e.g. ["some", "path", "to"])
74
+ */
75
+
76
+ // Short descriptions (no extra newlines needed)
77
+ /**
78
+ * Log an info message
79
+ *
80
+ * @param {string} message - Log message
81
+ * @param {*} [details] - Additional details
82
+ *
83
+ * @returns {boolean} True if the log was emitted
84
+ */
85
+ ```
86
+ - **Concise descriptions** - avoid obvious/redundant explanations
87
+ - Keep only essential information that adds value for developers
88
+ - Remove descriptions that simply restate parameter names or types
89
+ - Examples:
90
+ - ✅ `@property {number} [exp] - Expiration time (seconds since epoch)`
91
+ - ❌ `@property {number} [exp] - Expiration time - timestamp when the JWT expires`
92
+ - ✅ `@property {boolean} [ignoreExpiration] - Skip expiration validation`
93
+ - ❌ `@property {boolean} [ignoreExpiration] - If true, do not validate the expiration of the token`
94
+
95
+ ## Writing Style
96
+ - Use normal English capitalization rules - avoid unnecessary capitals
97
+ - Don't capitalize common nouns like "server", "client", "button", "error", "validation", etc.
98
+ - Only capitalize proper nouns, beginnings of sentences, and official names
99
+ - Examples:
100
+ - ✅ "server-side validation" not "Server-side Validation"
101
+ - ✅ "expect function" not "Expect Function"
102
+ - ✅ "client error" not "Client Error"
103
+ - ✅ "JavaScript" (proper noun) but "validation error" (common noun)
104
+
105
+ ## Import Path Conventions
106
+ - Use `$lib/domain/...` imports for cross-domain references (e.g., `$lib/media/image.js`, `$lib/network/http.js`)
107
+ - Use relative imports (`./` or `../`) when staying within the same main folder under `$lib`
108
+ - **Always include file extensions** (`.js`, `.svelte`) in import statements
109
+ - **For cross-domain imports, use specific export files** (e.g., `parsers.js`, `valibot.js`) rather than directory-only paths - this ensures compatibility outside the library
110
+ - **For local imports within the same domain**, import specific files directly (e.g., `./ClassName.js`) rather than using local index files
111
+ - Examples:
112
+ - ✅ `import { ImageLoader } from '$lib/media/image.js'` (cross-domain import)
113
+ - ✅ `import ImageLoader from './ImageLoader.svelte.js'` (local import within same domain)
114
+ - ✅ `import IterableTree from './IterableTree.js'` (local import within same domain)
115
+ - ✅ `import { v } from '$lib/valibot/valibot.js'` (cross-domain with specific export file)
116
+ - ✅ `import { HumanUrl, Email } from '$lib/valibot/parsers.js'` (cross-domain with specific export file)
117
+ - ❌ `import { v, HumanUrl } from '$lib/valibot'` (missing specific export file)
118
+ - ❌ `import { IterableTree } from './index.js'` (local index when specific file should be used)
119
+ - ❌ `import something from '../../media/image.js'` (cross-domain relative import)
120
+
121
+ ## Class Export Conventions
122
+ - **All classes should be default exports**: `export default class ClassName`
123
+ - **Import classes without destructuring**: `import ClassName from './ClassName.js'`
124
+ - Examples:
125
+ - ✅ `export default class HkPromise extends Promise {}`
126
+ - ✅ `import HkPromise from './HkPromise.js'`
127
+ - ❌ `export class HkPromise extends Promise {}` (named export)
128
+ - ❌ `import { HkPromise } from './HkPromise.js'` (destructuring import)
129
+
130
+ ## Accessibility Requirements
131
+ - Proper ARIA roles, states, and properties
132
+ - Descriptive aria-labels for interactive elements
133
+ - Keyboard navigation support
134
+ - Logical tab order and focus management
135
+ - Proper heading hierarchy
136
+ - Screen reader compatibility (VoiceOver, NVDA)
137
+
138
+ ## Common Patterns to Follow
139
+ - Server/client code separation in SvelteKit
140
+ - Clear component hierarchy
141
+ - Minimal, targeted changes to working code
142
+ - Ask before making assumptions about existing structure
143
+ - Focus on specific requests rather than general improvements
144
+
145
+ ## Design System Usage in Examples
146
+
147
+ When creating examples in `routes/examples/`, always use the HKdigital Design System:
148
+
149
+ ### Typography
150
+ - Use complete typography classes: `type-heading-h1`, `type-base-md`, `type-ui-sm`
151
+ - Include dark mode variants when relevant: `type-heading-h1-dark`
152
+ - Never use raw Tailwind text classes like `text-lg` - use `text-base-lg` instead
153
+
154
+ ### Spacing
155
+ - Use UI points for element spacing: `p-20up`, `m-10up`, `gap-16up`
156
+ - Use text-based spacing for typography-related spacing: `mb-16bt`, `mt-12ut`
157
+ - Never use raw Tailwind spacing like `p-4` - use `p-4up` instead
158
+
159
+ ### Colors
160
+ - Use themed colors: `bg-primary-500`, `bg-surface-100`, `text-error-500`
161
+ - Always use contrast colors for accessibility: `text-primary-contrast-500`
162
+ - Include both light and dark mode considerations
163
+
164
+ ### Layout & Components
165
+ - Use design system utilities: `rounded-md`, `border-width-normal`
166
+ - Follow the responsive scaling system built around 1024×768 design reference
167
+ - Use component data attributes: `data-component="button"` `data-role="primary"`
168
+
169
+ ### Custom Styling for Examples
170
+ When examples require custom CSS beyond the design system:
171
+
172
+ - Always add a `data-page` attribute to the outer page element
173
+ - Create a `style.css` file alongside the `+page.svelte` file
174
+ - Use `<style src="./style.css"></style>` to include the styles
175
+ - Scope all CSS rules under `[data-page]` to prevent global conflicts
176
+ - Use CSS nesting syntax for better organization
177
+
178
+ **Example structure:**
179
+ ```svelte
180
+ <!-- +page.svelte -->
181
+ <div data-page>
182
+ <div data-section="content">
183
+ <!-- example content -->
184
+ </div>
185
+ </div>
186
+
187
+ <style src="./style.css"></style>
188
+ ```
189
+
190
+ ```css
191
+ /* style.css */
192
+ [data-page] {
193
+ & [data-section="content"] {
194
+ /* scoped styles here */
195
+ position: relative;
196
+ padding: 20px;
197
+ }
198
+
199
+ & .custom-element {
200
+ /* more scoped styles */
201
+ }
202
+ }
203
+ ```
204
+
205
+ ### Structure
206
+ - Always include proper heading hierarchy (`type-heading-h1`, `type-heading-h2`, etc.)
207
+ - Use semantic HTML with appropriate ARIA attributes
208
+ - Follow WCAG 2.1 Level AA accessibility guidelines
209
+
210
+ ### UI Components
211
+ - Always use components from `$lib/ui/primitives/` when available
212
+ - Prefer the `Button` component over raw `<button>` elements
213
+ - Import from the index: `import { Button } from '$lib/ui/primitives.js'`
214
+ - Use snippet syntax: `<Button>{content}</Button>` instead of slot syntax
215
+
216
+ ### Example Template
217
+ ```svelte
218
+ <script>
219
+ import { Button } from '$lib/ui/primitives.js';
220
+ </script>
221
+
222
+ <div class="container mx-auto p-20up" data-page>
223
+ <h1 class="type-heading-h1 mb-20up">Example Title</h1>
224
+
225
+ <div class="card p-20up mb-20up">
226
+ <p class="type-base-md mb-12bt">Description text</p>
227
+ <Button>
228
+ Action
229
+ </Button>
230
+ </div>
231
+ </div>
232
+
233
+ <!-- Only include if custom CSS is needed -->
234
+ <style src="./style.css"></style>
235
+ ```
236
+
237
+ ## Styling System & Tailwind CSS
238
+
239
+ ### Critical: Design System Spacing Values
240
+
241
+ **IMPORTANT**: Only use spacing values that exist in the design system configuration. Invalid spacing utilities will cause build failures.
242
+
243
+ #### Available Viewport-Based Spacing (`up` suffix)
244
+ Valid values: `1up`, `2up`, `4up`, `5up`, `6up`, `10up`, `20up`, `30up`, `40up`, `50up`, `60up`, `70up`, `80up`, `90up`, `100up`, `120up`, `140up`, `160up`, `180up`, `200up`
245
+
246
+ #### Available Text-Based Spacing (`ut`, `bt`, `ht` suffixes)
247
+ Valid values: `1ut/bt/ht`, `2ut/bt/ht`, `4ut/bt/ht`, `6ut/bt/ht`, `8ut/bt/ht`, `10ut/bt/ht`, `11ut/bt/ht`, `12ut/bt/ht`, `16ut/bt/ht`, `20ut/bt/ht`, `24ut/bt/ht`, `28ut/bt/ht`, `32ut/bt/ht`, `36ut/bt/ht`, `50ut/bt/ht`
248
+
249
+ #### ❌ Common Invalid Values (Will Cause Build Failures)
250
+ - `p-16up` (use `p-20up` instead)
251
+ - `px-16up py-12up` (use `px-20up py-10up` instead)
252
+ - `mb-16up` (use `mb-20up` instead)
253
+ - Any spacing value not listed above
254
+
255
+ ### External CSS Files (`<style src="./style.css">`)
256
+
257
+ When using external CSS files with `@apply` directives, you **MUST** include the `@reference` directive:
258
+
259
+ #### ✅ Correct External CSS
260
+ ```css
261
+ /* style.css */
262
+ @reference '../../app.css';
263
+
264
+ [data-page] {
265
+ & .my-component {
266
+ @apply p-20up bg-surface-300 border border-primary-500;
267
+ }
268
+ }
269
+ ```
270
+
271
+ #### ❌ Broken External CSS
272
+ ```css
273
+ /* style.css - MISSING @reference */
274
+ [data-page] {
275
+ & .my-component {
276
+ @apply p-20up bg-surface-300; /* ERROR: Cannot apply unknown utility class */
277
+ }
278
+ }
279
+ ```
280
+
281
+ ### Path Resolution for @reference
282
+
283
+ The `@reference` path must be relative to your CSS file's location:
284
+ - From `/src/routes/examples/style.css` → `@reference '../../app.css'`
285
+ - From `/src/routes/examples/ui/style.css` → `@reference '../../../app.css'`
286
+ - From `/src/lib/components/style.css` → `@reference '../../app.css'`
287
+
288
+ ### Inline vs External CSS
289
+
290
+ #### Inline Styles (No @reference needed)
291
+ ```svelte
292
+ <style>
293
+ [data-page] {
294
+ & .my-component {
295
+ @apply p-20up bg-surface-300 border border-primary-500;
296
+ }
297
+ }
298
+ </style>
299
+ ```
300
+
301
+ #### External CSS (Requires @reference)
302
+ ```svelte
303
+ <!-- Component.svelte -->
304
+ <div class="my-component">Content</div>
305
+ <style src="./style.css"></style>
306
+ ```
307
+
308
+ ### Troubleshooting Build Errors
309
+
310
+ #### "Cannot apply unknown utility class 'p-XYZup'"
311
+ 1. Check if the spacing value exists in `VIEWPORT_POINT_SIZES` or `TEXT_POINT_SIZES`
312
+ 2. Replace with the nearest valid value (e.g., `16up` → `20up`)
313
+ 3. If using external CSS, verify `@reference` directive is present and path is correct
314
+
315
+ #### "Are you using CSS modules or similar and missing @reference?"
316
+ 1. Add `@reference '../../app.css'` at the top of your external CSS file
317
+ 2. Verify the relative path from CSS file to `src/app.css` is correct
318
+ 3. Consider switching to inline styles if path resolution is problematic
319
+
320
+ ### Design System Integration
321
+
322
+ #### Always Use Design System Classes
323
+ - ✅ `type-heading-h1`, `type-base-md`, `type-ui-sm`
324
+ - ✅ `p-20up`, `m-10up`, `gap-16up` (viewport-based)
325
+ - ✅ `mb-16bt`, `mt-12ut` (text-based)
326
+ - ✅ `bg-surface-300`, `text-primary-500`, `border-error-500`
327
+ - ❌ Raw Tailwind: `text-lg`, `p-4`, `bg-gray-300`
328
+
329
+ #### Color System
330
+ All design system colors are available with contrast variants:
331
+ - Base colors: `bg-primary-500`, `bg-surface-100`, `bg-error-500`
332
+ - Contrast colors: `text-primary-contrast-500`, `text-surface-contrast-100`
333
+ - Shades: `50`, `100`, `200`, `300`, `400`, `500`, `600`, `700`, `800`, `900`, `950`
334
+
335
+ ### CSS Architecture
336
+ - Use `[data-page]` scoping for page-specific styles
337
+ - Use `[data-component]` attributes for component identification
338
+ - Prefer CSS nesting with `&` selector
339
+ - Layer styles: `@layer theme, base, utilities, components`
340
+
341
+ ## What Not to Do
342
+ - Don't use deprecated Svelte 4 syntax
343
+ - Don't mix slot and snippet syntax
344
+ - Don't use TypeScript syntax
345
+ - Don't use CommonJS (require/module.exports)
346
+ - Don't use underscore prefixes for private methods
347
+ - Don't use invalid spacing values (e.g., `p-16up`, `mb-14up`) - check design system configuration
348
+ - Don't use external CSS with `@apply` without the `@reference` directive
349
+ - Don't modify unrelated code unless necessary
350
+ - **NEVER run `npm run dev` or `pnpm run dev`** - it interferes with the user's running development server
@@ -1,5 +1,5 @@
1
1
  export { createServerLogger } from "./internal/factories/server.js";
2
2
  export { createClientLogger } from "./internal/factories/client.js";
3
3
  export { Logger } from "./internal/logger/index.js";
4
- export * from "./constants.js";
4
+ export * from "./levels.js";
5
5
  export * from "./typedef.js";
@@ -5,6 +5,6 @@ export { createClientLogger } from './internal/factories/client.js';
5
5
  // Logger (for advanced usage)
6
6
  export { Logger } from './internal/logger/index.js';
7
7
 
8
- // Constants and typedefs
9
- export * from './constants.js';
8
+ export * from './levels.js';
9
+
10
10
  export * from './typedef.js';
@@ -1,5 +1,5 @@
1
1
  import { dev } from '$app/environment';
2
- import { LEVELS } from '../../constants.js';
2
+ import { LEVELS } from '../../levels.js';
3
3
  import {
4
4
  findRelevantFrameIndex,
5
5
  detectErrorMeta,
@@ -1,6 +1,6 @@
1
1
  import { Logger } from '../logger/index.js';
2
2
  import { ConsoleAdapter } from '../adapters/console.js';
3
- import { INFO } from '../../constants.js';
3
+ import { INFO } from '../../levels.js';
4
4
 
5
5
  /**
6
6
  * Create a client-side logger with console adapter
@@ -1,6 +1,6 @@
1
1
  import { Logger } from '../logger/index.js';
2
2
  import { PinoAdapter } from '../adapters/pino.js';
3
- import { INFO } from '../../constants.js';
3
+ import { INFO } from '../../levels.js';
4
4
  // import { expectNoSSRContext } from '../../../util/ssr/index.js';
5
5
 
6
6
  /**
@@ -43,7 +43,7 @@ import {
43
43
  ERROR,
44
44
  LEVELS,
45
45
  LOG
46
- } from '../../constants.js';
46
+ } from '../../levels.js';
47
47
 
48
48
  import { DetailedError } from '../../../generic/errors.js';
49
49
  // import { LoggerError } from '../../errors.js';
@@ -8,36 +8,23 @@
8
8
  * @property {AudioLoader} audioLoader
9
9
  * @property {SourceConfig} [config]
10
10
  */
11
- export default class AudioScene {
12
- state: string;
13
- loaded: boolean;
11
+ export default class AudioScene extends SceneBase {
14
12
  muted: boolean;
15
13
  targetGain: number;
16
14
  /**
17
- * Get audio scene loading progress
18
- */
19
- get progress(): {
20
- totalBytesLoaded: number;
21
- totalSize: number;
22
- sourcesLoaded: number;
23
- numberOfSources: number;
24
- };
25
- /**
26
- * Get audio scene abort progress
27
- */
28
- get abortProgress(): {
29
- sourcesAborted: number;
30
- numberOfSources: number;
31
- };
32
- /**
33
- * Start loading all audio sources
15
+ * Get the array of memory sources managed by this scene
16
+ *
17
+ * @returns {MemorySource[]}
34
18
  */
35
- load(): void;
19
+ get sources(): MemorySource[];
36
20
  /**
37
- * Abort loading all audio sources
21
+ * Extract the audio loader from a source object
22
+ *
23
+ * @param {MemorySource} source
24
+ *
25
+ * @returns {AudioLoader}
38
26
  */
39
- abort(): void;
40
- destroy(): void;
27
+ getLoaderFromSource(source: MemorySource): AudioLoader;
41
28
  /**
42
29
  * Add in-memory audio source
43
30
  * - Uses an AudioLoader instance to load audio data from network
@@ -67,18 +54,33 @@ export default class AudioScene {
67
54
  */
68
55
  setAudioContext(audioContext?: AudioContext): void;
69
56
  /**
70
- * Set target gain
57
+ * Set target gain (volume level) for all audio in this scene
58
+ * - Currently applies immediately, but "target" allows for future
59
+ * smooth transitions using Web Audio API's gain scheduling
60
+ * - Range: 0.0 (silence) to 1.0 (original) to 1.0+ (amplified)
71
61
  *
72
- * @param {number} value
62
+ * @param {number} value - Target gain value (0.0 to 1.0+)
73
63
  */
74
64
  setTargetGain(value: number): void;
75
65
  /**
76
- * Get the scene gain
66
+ * Get the current target gain (volume level)
77
67
  *
78
- * @returns {number} value
68
+ * @returns {number} Target gain value (0.0 to 1.0+)
79
69
  */
80
70
  getTargetGain(): number;
71
+ /**
72
+ * Mute all audio in this scene
73
+ * - Saves current volume level for restoration
74
+ * - Sets target gain to 0 (silence)
75
+ * - Safe to call multiple times
76
+ */
81
77
  mute(): void;
78
+ /**
79
+ * Unmute all audio in this scene
80
+ * - Restores volume level from before muting
81
+ * - Safe to call multiple times
82
+ * - No effect if scene is not currently muted
83
+ */
82
84
  unmute(): void;
83
85
  #private;
84
86
  }
@@ -91,4 +93,5 @@ export type MemorySource = {
91
93
  audioLoader: AudioLoader;
92
94
  config?: SourceConfig;
93
95
  };
96
+ import SceneBase from '../base/SceneBase.svelte.js';
94
97
  import AudioLoader from './AudioLoader.svelte.js';