@hkdigital/lib-sveltekit 0.1.43 → 0.1.45

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.
@@ -1,2 +1,2 @@
1
- export { default as ImageLoader } from "./ImageLoader.svelte";
2
- export { default as ImageVariantsLoader } from "./ImageVariantsLoader.svelte";
1
+ export { default as ImageLoader } from "./ImageLoader.svelte.js";
2
+ export { default as ImageVariantsLoader } from "./ImageVariantsLoader.svelte.js";
@@ -1,4 +1,4 @@
1
- export { default as ImageLoader } from './ImageLoader.svelte';
2
- export { default as ImageVariantsLoader } from './ImageVariantsLoader.svelte';
1
+ export { default as ImageLoader } from './ImageLoader.svelte.js';
2
+ export { default as ImageVariantsLoader } from './ImageVariantsLoader.svelte.js';
3
3
 
4
4
  // export * from './constants.js';
@@ -1,2 +1,2 @@
1
- export { default as NetworkLoader } from "./NetworkLoader.svelte";
1
+ export { default as NetworkLoader } from "./NetworkLoader.svelte.js";
2
2
  export * from "./constants.js";
@@ -1,3 +1,3 @@
1
- export { default as NetworkLoader } from './NetworkLoader.svelte';
1
+ export { default as NetworkLoader } from './NetworkLoader.svelte.js';
2
2
 
3
3
  export * from './constants.js';
@@ -11,6 +11,7 @@
11
11
  * size?: 'sm' | 'md' | 'lg',
12
12
  * variant?: string,
13
13
  * mode?: 'light'|'dark'
14
+ * buttonType?: 'button' | 'submit' | 'reset',
14
15
  * active?: boolean,
15
16
  * selected?: boolean,
16
17
  * loading?: boolean,
@@ -34,6 +35,8 @@
34
35
  variant = '',
35
36
  mode = 'light',
36
37
 
38
+ buttonType = 'button',
39
+
37
40
  // States
38
41
  active = $bindable(false),
39
42
  selected = $bindable(false),
@@ -62,7 +65,7 @@
62
65
  data-size={size}
63
66
  data-variant={variant}
64
67
  data-mode={mode}
65
- type="button"
68
+ type={buttonType}
66
69
  class="{base} {bg} {classes} {stateClasses}"
67
70
  disabled={disabled || loading}
68
71
  aria-busy={loading}
@@ -9,6 +9,7 @@ declare const Button: import("svelte").Component<{
9
9
  size?: "sm" | "md" | "lg";
10
10
  variant?: string;
11
11
  mode?: "light" | "dark";
12
+ buttonType?: "button" | "submit" | "reset";
12
13
  active?: boolean;
13
14
  selected?: boolean;
14
15
  loading?: boolean;
@@ -1,8 +1,9 @@
1
1
  /**
2
2
  * @callback requestHandler
3
- * @param {AbortController} controller
4
- * @param {( reason?: Error ) => void} abort
5
- * @param {( delayMs: number) => void} timeout
3
+ * @param {Object} _
4
+ * @param {AbortController} _.controller
5
+ * @param {( reason?: Error ) => void} _.abort
6
+ * @param {( delayMs: number) => void} _.timeout
6
7
  */
7
8
  /**
8
9
  * Make GET request
@@ -105,4 +106,8 @@ export function httpRequest({ method, url, urlSearchParams, body, headers, reque
105
106
  requestHandler?: requestHandler;
106
107
  timeoutMs?: number;
107
108
  }): Promise<Response>;
108
- export type requestHandler = (controller: AbortController, abort: (reason?: Error) => void, timeout: (delayMs: number) => void) => any;
109
+ export type requestHandler = (_: {
110
+ controller: AbortController;
111
+ abort: (reason?: Error) => void;
112
+ timeout: (delayMs: number) => void;
113
+ }) => any;
@@ -13,9 +13,10 @@ import { waitForAndCheckResponse } from './response.js';
13
13
 
14
14
  /**
15
15
  * @callback requestHandler
16
- * @param {AbortController} controller
17
- * @param {( reason?: Error ) => void} abort
18
- * @param {( delayMs: number) => void} timeout
16
+ * @param {Object} _
17
+ * @param {AbortController} _.controller
18
+ * @param {( reason?: Error ) => void} _.abort
19
+ * @param {( delayMs: number) => void} _.timeout
19
20
  */
20
21
 
21
22
  /**
@@ -41,7 +42,13 @@ import { waitForAndCheckResponse } from './response.js';
41
42
  *
42
43
  * @returns {Promise<Response>} responsePromise
43
44
  */
44
- export async function httpGet({ url, urlSearchParams, headers, requestHandler, timeoutMs }) {
45
+ export async function httpGet({
46
+ url,
47
+ urlSearchParams,
48
+ headers,
49
+ requestHandler,
50
+ timeoutMs
51
+ }) {
45
52
  const responsePromise = httpRequest({
46
53
  method: METHOD_GET,
47
54
  url,
@@ -76,7 +83,13 @@ export async function httpGet({ url, urlSearchParams, headers, requestHandler, t
76
83
  *
77
84
  * @returns {Promise<Response>} responsePromise
78
85
  */
79
- export async function httpPost({ url, body = null, headers, requestHandler, timeoutMs }) {
86
+ export async function httpPost({
87
+ url,
88
+ body = null,
89
+ headers,
90
+ requestHandler,
91
+ timeoutMs
92
+ }) {
80
93
  const responsePromise = httpRequest({
81
94
  method: METHOD_POST,
82
95
  url,
@@ -142,7 +155,10 @@ export async function httpRequest({
142
155
  if (headers) {
143
156
  setRequestHeaders(requestHeaders, headers);
144
157
 
145
- if (headers[CONTENT_TYPE] === APPLICATION_JSON && typeof body !== 'string') {
158
+ if (
159
+ headers[CONTENT_TYPE] === APPLICATION_JSON &&
160
+ typeof body !== 'string'
161
+ ) {
146
162
  throw new Error(
147
163
  `Trying to send request with [content-type:${APPLICATION_JSON}], ` +
148
164
  'but body is not a (JSON encoded) string.'
@@ -151,6 +167,7 @@ export async function httpRequest({
151
167
  // IDEA: try to decode the body to catch errors on client side
152
168
  }
153
169
 
170
+ /** @type {RequestInit} */
154
171
  const init = {
155
172
  mode: 'cors',
156
173
  cache: 'no-cache',
@@ -165,7 +182,8 @@ export async function httpRequest({
165
182
  if (urlSearchParams) {
166
183
  if (!(urlSearchParams instanceof URLSearchParams)) {
167
184
  throw new Error(
168
- 'Invalid parameter [urlSearchParams] ' + '(expected instanceof URLSearchParams)'
185
+ 'Invalid parameter [urlSearchParams] ' +
186
+ '(expected instanceof URLSearchParams)'
169
187
  );
170
188
  }
171
189
 
@@ -174,7 +192,8 @@ export async function httpRequest({
174
192
  for (const [name, value] of urlSearchParams.entries()) {
175
193
  if (existingParams.has(name)) {
176
194
  throw new Error(
177
- `Cannot set URL search parameter [${name}] ` + `in url [${url.href}] (already set)`
195
+ `Cannot set URL search parameter [${name}] ` +
196
+ `in url [${url.href}] (already set)`
178
197
  );
179
198
  }
180
199
 
@@ -246,10 +265,12 @@ export async function httpRequest({
246
265
  * @param {number} delayMs
247
266
  */
248
267
  const timeout = (delayMs = 10000) => {
249
- expect.positiveNumber(delayMs, 'Invalid value for [delayMs]');
268
+ expect.positiveNumber(delayMs);
250
269
 
251
270
  const timerId = setTimeout(() => {
252
- controller.abort(new TimeoutError(`Request [${url.href}] timed out [${delayMs}]`));
271
+ controller.abort(
272
+ new TimeoutError(`Request [${url.href}] timed out [${delayMs}]`)
273
+ );
253
274
  }, delayMs);
254
275
 
255
276
  promise.finally(() => {
@@ -262,7 +283,7 @@ export async function httpRequest({
262
283
  }
263
284
 
264
285
  if (requestHandler) {
265
- expect.function(requestHandler, 'Invalid parameter [requestHandler]');
286
+ expect.function(requestHandler);
266
287
 
267
288
  requestHandler({ controller, abort, timeout });
268
289
  }
@@ -2,7 +2,10 @@ import { ResponseError } from '../../constants/errors/index.js';
2
2
  import * as expect from '../expect/index.js';
3
3
  import { toURL } from './url.js';
4
4
 
5
- import { WWW_AUTHENTICATE, CONTENT_LENGTH } from '../../constants/http/headers.js';
5
+ import {
6
+ WWW_AUTHENTICATE,
7
+ CONTENT_LENGTH
8
+ } from '../../constants/http/headers.js';
6
9
 
7
10
  import { href } from './url.js';
8
11
 
@@ -69,7 +72,8 @@ export async function expectResponseOk(response, url) {
69
72
  const error = await getErrorFromResponse(response);
70
73
 
71
74
  throw new ResponseError(
72
- `Server returned - ${response.status} ${response.statusText} ` + `[url=${href(url)}]`,
75
+ `Server returned - ${response.status} ${response.statusText} ` +
76
+ `[url=${href(url)}]`,
73
77
  { cause: error }
74
78
  );
75
79
  }
@@ -120,9 +124,12 @@ export async function waitForAndCheckResponse(responsePromise, url) {
120
124
  }
121
125
  } catch (e) {
122
126
  if (e instanceof TypeError || response?.ok === false) {
123
- throw new ResponseError(`A network error occurred for request [${href(url)}]`, {
124
- cause: e
125
- });
127
+ throw new ResponseError(
128
+ `A network error occurred for request [${href(url)}]`,
129
+ {
130
+ cause: e
131
+ }
132
+ );
126
133
  } else {
127
134
  throw e;
128
135
  }
@@ -148,7 +155,7 @@ export function loadResponseBuffer(response, onProgress) {
148
155
 
149
156
  let bytesLoaded = 0;
150
157
 
151
- if (onProgress && size) {
158
+ if (onProgress /*&& size*/) {
152
159
  onProgress({ bytesLoaded, size });
153
160
  }
154
161
 
@@ -182,12 +189,14 @@ export function loadResponseBuffer(response, onProgress) {
182
189
  // console.log({ size, bytesLoaded, value });
183
190
 
184
191
  if (size && bytesLoaded > size) {
185
- throw new Error(`Received more bytes that specified by header content-length`);
192
+ throw new Error(
193
+ `Received more bytes that specified by header content-length`
194
+ );
186
195
  }
187
196
 
188
197
  chunks.push(value);
189
198
 
190
- if (onProgress && size) {
199
+ if (onProgress /*&& size*/) {
191
200
  onProgress({ bytesLoaded, size });
192
201
  }
193
202
  }
@@ -199,7 +208,9 @@ export function loadResponseBuffer(response, onProgress) {
199
208
  } // end while
200
209
 
201
210
  if (size && bytesLoaded !== size) {
202
- throw new Error(`Received [${bytesLoaded}], but expected [${size}] bytes`);
211
+ throw new Error(
212
+ `Received [${bytesLoaded}], but expected [${size}] bytes`
213
+ );
203
214
  }
204
215
 
205
216
  // Concat the chinks into a single array
File without changes
File without changes
@@ -26,11 +26,15 @@ export class PresenterState {
26
26
  /** @type {string} */
27
27
  currentSlideName: string;
28
28
  /** @type {string} */
29
+ nextSlideName: string;
30
+ /** @type {string} */
29
31
  pendingSlideName: string;
30
32
  /** @type {boolean} */
31
33
  configured: boolean;
32
- /** @type {Map<Symbol, () => void>} */
33
- onUpdateListeners: Map<Symbol, () => void>;
34
+ /** @type {Map<Symbol, ( params: ListenerParams ) => void>} */
35
+ onBeforeListeners: Map<Symbol, (params: ListenerParams) => void>;
36
+ /** @type {Map<Symbol, ( params: ListenerParams ) => void>} */
37
+ onShowListeners: Map<Symbol, (params: ListenerParams) => void>;
34
38
  /**
35
39
  * Configure the presentation
36
40
  *
@@ -64,25 +68,6 @@ export class PresenterState {
64
68
  export type Slide = import("./typedef").Slide;
65
69
  export type Transition = import("./typedef").Transition;
66
70
  export type Layer = import("./typedef").Layer;
67
- export type LoadController = {
68
- /**
69
- * - Function to call when loading is complete
70
- */
71
- loaded: () => void;
72
- /**
73
- * - Function to return to the previous slide
74
- */
75
- cancel: () => void;
76
- };
77
- export type PresenterRef = {
78
- /**
79
- * - Navigate to a slide by name
80
- */
81
- gotoSlide: (name: string) => void;
82
- /**
83
- * - Get the current slide name
84
- */
85
- getCurrentSlideName: () => string;
86
- onUpdate: (callback: any) => Function;
87
- };
71
+ export type PresenterRef = import("./typedef").Layer;
72
+ export type LoadController = import("./typedef").Layer;
88
73
  import { HkPromise } from '../../classes/promise/index.js';
@@ -6,6 +6,8 @@ import { untrack } from 'svelte';
6
6
 
7
7
  import { HkPromise } from '../../classes/promise/index.js';
8
8
 
9
+ import { STAGE_BEFORE, STAGE_SHOW } from './constants.js';
10
+
9
11
  /**
10
12
  * @typedef {import("./typedef").Slide} Slide
11
13
  */
@@ -19,16 +21,11 @@ import { HkPromise } from '../../classes/promise/index.js';
19
21
  */
20
22
 
21
23
  /**
22
- * @typedef {Object} LoadController
23
- * @property {() => void} loaded - Function to call when loading is complete
24
- * @property {() => void} cancel - Function to return to the previous slide
24
+ * @typedef {import("./typedef").Layer} PresenterRef
25
25
  */
26
26
 
27
27
  /**
28
- * @typedef {Object} PresenterRef
29
- * @property {(name: string) => void} gotoSlide - Navigate to a slide by name
30
- * @property {() => string} getCurrentSlideName - Get the current slide name
31
- * @property {(callback)=>Function} onUpdate
28
+ * @typedef {import("./typedef").Layer} LoadController
32
29
  */
33
30
 
34
31
  const Z_BACK = 0;
@@ -89,14 +86,20 @@ export class PresenterState {
89
86
  return currentSlide?.name || '';
90
87
  });
91
88
 
89
+ /** @type {string} */
90
+ nextSlideName;
91
+
92
92
  /** @type {string} */
93
93
  pendingSlideName;
94
94
 
95
95
  /** @type {boolean} */
96
96
  configured = false;
97
97
 
98
- /** @type {Map<Symbol, () => void>} */
99
- onUpdateListeners = new Map();
98
+ /** @type {Map<Symbol, ( params: ListenerParams ) => void>} */
99
+ onBeforeListeners = new Map();
100
+
101
+ /** @type {Map<Symbol, ( params: ListenerParams ) => void>} */
102
+ onShowListeners = new Map();
100
103
 
101
104
  /**
102
105
  * Initialize the presenter state and set up reactivity
@@ -281,11 +284,19 @@ export class PresenterState {
281
284
  throw new Error('Not configured yet');
282
285
  }
283
286
 
287
+ if (slide.name === this.currentSlideName) {
288
+ throw new Error(`gotoSlide cannot transition to current slide`);
289
+ }
290
+
291
+ this.nextSlideName = slide.name;
292
+
284
293
  if (this.busy) {
285
294
  this.pendingSlideName = slide.name;
286
295
  return;
287
296
  }
288
297
 
298
+ this.#callOnBeforeListeners();
299
+
289
300
  this.slideLoadingPromise = null;
290
301
 
291
302
  // Get a presenter reference to pass to the slide
@@ -396,6 +407,7 @@ export class PresenterState {
396
407
  if (this.pendingSlideName) {
397
408
  const pendingName = this.pendingSlideName;
398
409
 
410
+ this.nextSlideName = pendingName;
399
411
  this.pendingSlideName = null;
400
412
 
401
413
  untrack(() => {
@@ -403,14 +415,26 @@ export class PresenterState {
403
415
  this.gotoSlide(pendingName);
404
416
  }
405
417
  });
418
+ } else {
419
+ this.nextSlideName = null;
406
420
  }
407
421
 
408
- this.#CallUpdateListeners();
422
+ this.#callOnShowListeners();
409
423
  }
410
424
 
411
- #CallUpdateListeners() {
412
- for (const fn of this.onUpdateListeners.values()) {
413
- fn();
425
+ #callOnBeforeListeners() {
426
+ let nextSlideName = this.nextSlideName;
427
+
428
+ for (const fn of this.onBeforeListeners.values()) {
429
+ fn({ stage: STAGE_BEFORE, slideName: nextSlideName });
430
+ }
431
+ }
432
+
433
+ #callOnShowListeners() {
434
+ let currentSlideName = this.currentSlideName;
435
+
436
+ for (const fn of this.onShowListeners.values()) {
437
+ fn({ stage: STAGE_SHOW, slideName: currentSlideName });
414
438
  }
415
439
  }
416
440
 
@@ -557,12 +581,20 @@ export class PresenterState {
557
581
  return {
558
582
  gotoSlide: (name) => this.gotoSlide(name),
559
583
  getCurrentSlideName: () => this.currentSlideName,
560
- onUpdate: (callback) => {
584
+ onBefore: (callback) => {
585
+ const key = Symbol();
586
+ this.onBeforeListeners.set(key, callback);
587
+
588
+ return () => {
589
+ this.onBeforeListeners.delete(key);
590
+ };
591
+ },
592
+ onAfter: (callback) => {
561
593
  const key = Symbol();
562
- this.onUpdateListeners.set(key, callback);
594
+ this.onShowListeners.set(key, callback);
563
595
 
564
596
  return () => {
565
- this.onUpdateListeners.delete(key);
597
+ this.onShowListeners.delete(key);
566
598
  };
567
599
  }
568
600
  };
@@ -1,3 +1,5 @@
1
1
  export const TRANSITION_CSS: "css";
2
2
  export const FADE_IN: "fade-in";
3
3
  export const FADE_OUT: "fade-out";
4
+ export const STAGE_BEFORE: "stage-before";
5
+ export const STAGE_SHOW: "stage-show";
@@ -2,3 +2,6 @@ export const TRANSITION_CSS = 'css';
2
2
 
3
3
  export const FADE_IN = 'fade-in';
4
4
  export const FADE_OUT = 'fade-out';
5
+
6
+ export const STAGE_BEFORE = 'stage-before';
7
+ export const STAGE_SHOW = 'stage-show';
@@ -25,6 +25,31 @@ export type FadeOutTransition = {
25
25
  duration?: number;
26
26
  timing?: string;
27
27
  };
28
+ export type ListenerParams = {
29
+ stage: string;
30
+ slideName: string;
31
+ };
32
+ export type LoadController = {
33
+ /**
34
+ * - Function to call when loading is complete
35
+ */
36
+ loaded: () => void;
37
+ /**
38
+ * - Function to return to the previous slide
39
+ */
40
+ cancel: () => void;
41
+ };
42
+ export type PresenterRef = {
43
+ /**
44
+ * - Navigate to a slide by name
45
+ */
46
+ gotoSlide: (name: string) => void;
47
+ /**
48
+ * - Get the current slide name
49
+ */
50
+ getCurrentSlideName: () => string;
51
+ onUpdate: (callback: any) => Function;
52
+ };
28
53
  export type Transition = CssTransition | FadeInTransition | FadeOutTransition;
29
54
  export type SlideData = {
30
55
  [attrs: string]: any;
@@ -32,6 +32,26 @@
32
32
  * }} FadeOutTransition
33
33
  */
34
34
 
35
+ /**
36
+ * @typedef {{
37
+ * stage: string,
38
+ * slideName: string
39
+ * }} ListenerParams
40
+ */
41
+
42
+ /**
43
+ * @typedef {Object} LoadController
44
+ * @property {() => void} loaded - Function to call when loading is complete
45
+ * @property {() => void} cancel - Function to return to the previous slide
46
+ */
47
+
48
+ /**
49
+ * @typedef {Object} PresenterRef
50
+ * @property {(name: string) => void} gotoSlide - Navigate to a slide by name
51
+ * @property {() => string} getCurrentSlideName - Get the current slide name
52
+ * @property {(callback)=>Function} onUpdate
53
+ */
54
+
35
55
  /**
36
56
  * @typedef {CssTransition|FadeInTransition|FadeOutTransition} Transition
37
57
  */
@@ -25,7 +25,7 @@ export function waitForRender(callback) {
25
25
  setTimeout(() => {
26
26
  callback();
27
27
  resolve();
28
- }, 50);
28
+ }, 20);
29
29
  });
30
30
  });
31
31
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hkdigital/lib-sveltekit",
3
- "version": "0.1.43",
3
+ "version": "0.1.45",
4
4
  "author": {
5
5
  "name": "HKdigital",
6
6
  "url": "https://hkdigital.nl"