sveltekit-cache-first 0.0.1 → 0.0.3

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/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # SvelteKit Cache First
2
2
 
3
- A small library to make your SvelteKit Web App / PWA local first.
3
+ A small library to make your SvelteKit Web App / PWA use a cache first approach: instant second visit loads and fast performance on poor network conditions.
4
4
 
5
5
  ## Setup
6
6
 
@@ -11,14 +11,35 @@ npm install sveltekit-cache-first
11
11
  ```js
12
12
  // src/service-worker.js
13
13
  import { version, build, files } from '$service-worker';
14
- import { setupServiceWorker } from 'sveltekit-cache-first';
14
+ import { setupServiceWorker } from 'sveltekit-cache-first/sw';
15
15
 
16
16
  setupServiceWorker(self, { version, build, files });
17
17
  ```
18
18
 
19
+ #### Component method
20
+ ```svelte
21
+ <script>
22
+ import { UpdateAvailable } from 'sveltekit-cache-first';
23
+ </script>
24
+
25
+ <UpdateAvailable>
26
+ {#snippet children({ accept })}
27
+ <h2>An update is available</h2>
28
+ <p>Refresh to update</p>
29
+ <button onclick={() => accept()}>Refresh</button>
30
+ {/snippet}
31
+ </UpdateAvailable>
32
+
33
+ <!-- Optional -->
34
+ <!-- Note: This will disappear after the update has been detected, which may take a few seconds to appear. Only use this if your app must always be running the latest version. And if that is that is the case, strongly consider if cache-first is the right approach, or use other methods like api versioning. -->
35
+ <NoUpdate>
36
+ Main logic here
37
+ </NoUpdate>
38
+ ```
39
+
40
+ #### Custom handler method, using [svelte-sonner](https://github.com/wobsoriano/svelte-sonner)
19
41
  ```js
20
42
  // src/routes/+layout.svelte
21
- // Example using toast from svelte-sonner
22
43
  import { toast } from 'svelte-sonner';
23
44
  import { onUpdate } from 'sveltekit-cache-first';
24
45
 
@@ -26,7 +47,7 @@ onMount(() => {
26
47
  onUpdate((accept) => {
27
48
  // Your notification logic here, eg:
28
49
  toast('An update is available', {
29
- description: 'Refresh the page to update',
50
+ description: 'Refresh to update',
30
51
  action: {
31
52
  label: 'Refresh',
32
53
  onClick: () => accept()
@@ -41,8 +62,9 @@ onMount(() => {
41
62
  ```js
42
63
  // default values
43
64
  const options = {
44
- cachePageData: false, // Cache _data.json: data returned by load functions
45
- ignoredRoutes: ['/api'] // Routes to always fetch fresh for
46
- }
65
+ cachePageData: false, // Cache _data.json: data returned by load functions
66
+ ignoredRoutes: ['/api'] // Routes to always fetch fresh for
67
+ };
47
68
 
48
69
  setupServiceWorker(self, { version, build, files, options });
70
+ ```
package/dist/index.d.ts CHANGED
@@ -1,3 +1,4 @@
1
- import { setupServiceWorker } from "./sw.ts";
1
+ import UpdateAvailable from "./update-available.svelte";
2
2
  import { onUpdate } from "./update.ts";
3
- export { setupServiceWorker, onUpdate, };
3
+ import NoUpdate from "./no-update.svelte";
4
+ export { onUpdate, UpdateAvailable, NoUpdate };
package/dist/index.js CHANGED
@@ -1,4 +1,5 @@
1
1
  // Reexport your entry components here
2
- import { setupServiceWorker } from "./sw.js";
2
+ import UpdateAvailable from "./update-available.svelte";
3
3
  import { onUpdate } from "./update.js";
4
- export { setupServiceWorker, onUpdate, };
4
+ import NoUpdate from "./no-update.svelte";
5
+ export { onUpdate, UpdateAvailable, NoUpdate };
@@ -0,0 +1,17 @@
1
+ <script lang="ts">
2
+ import { onMount, type Snippet } from 'svelte';
3
+ import { onUpdate } from './update.js';
4
+
5
+ let { children }: { children?: Snippet } = $props();
6
+
7
+ let updateAvailable = $state(false);
8
+ onMount(() => {
9
+ onUpdate(() => {
10
+ updateAvailable = true;
11
+ });
12
+ });
13
+ </script>
14
+
15
+ {#if !updateAvailable}
16
+ {@render children?.()}
17
+ {/if}
@@ -0,0 +1,7 @@
1
+ import { type Snippet } from 'svelte';
2
+ type $$ComponentProps = {
3
+ children?: Snippet;
4
+ };
5
+ declare const NoUpdate: import("svelte").Component<$$ComponentProps, {}, "">;
6
+ type NoUpdate = ReturnType<typeof NoUpdate>;
7
+ export default NoUpdate;
@@ -0,0 +1,17 @@
1
+ <script lang="ts">
2
+ import { onMount, type Snippet } from 'svelte';
3
+ import { onUpdate } from './update.js';
4
+
5
+ let { children }: { children?: Snippet<[{ accept: () => void }]> } = $props();
6
+
7
+ let handleAccept: (() => void) | null = $state(null);
8
+ onMount(() => {
9
+ onUpdate((accept) => {
10
+ handleAccept = accept;
11
+ });
12
+ });
13
+ </script>
14
+
15
+ {#if handleAccept !== null}
16
+ {@render children?.({ accept: handleAccept })}
17
+ {/if}
@@ -0,0 +1,9 @@
1
+ import { type Snippet } from 'svelte';
2
+ type $$ComponentProps = {
3
+ children?: Snippet<[{
4
+ accept: () => void;
5
+ }]>;
6
+ };
7
+ declare const UpdateAvailable: import("svelte").Component<$$ComponentProps, {}, "">;
8
+ type UpdateAvailable = ReturnType<typeof UpdateAvailable>;
9
+ export default UpdateAvailable;
package/dist/update.d.ts CHANGED
@@ -1 +1 @@
1
- export declare function onUpdate(handle: (onAccept: () => void) => void): () => void;
1
+ export declare function onUpdate(handle: (onAccept: () => void) => void): void;
package/dist/update.js CHANGED
@@ -18,7 +18,9 @@ async function checkVersionChanged(worker) {
18
18
  function handleAccept(worker) {
19
19
  worker.postMessage({ type: 'SKLOCALFIRST_SKIP_WAITING' });
20
20
  }
21
- export function onUpdate(handle) {
21
+ const handlers = [];
22
+ let listenerSetUp = false;
23
+ function setupSWListener() {
22
24
  if (!('serviceWorker' in navigator)) {
23
25
  return () => { };
24
26
  }
@@ -29,7 +31,7 @@ export function onUpdate(handle) {
29
31
  if (reg.waiting) {
30
32
  const sw = reg.waiting;
31
33
  if (await checkVersionChanged(sw)) {
32
- handle(() => handleAccept(sw));
34
+ handlers.forEach((handle) => handle(() => handleAccept(sw)));
33
35
  }
34
36
  }
35
37
  // 2️⃣ Listen for new SW installations
@@ -39,8 +41,7 @@ export function onUpdate(handle) {
39
41
  return;
40
42
  sw.addEventListener('statechange', () => {
41
43
  if (sw.state === 'installed' && navigator.serviceWorker.controller) {
42
- // SW installed, new version waiting
43
- handle(() => handleAccept(sw));
44
+ handlers.forEach((handle) => handle(() => handleAccept(sw)));
44
45
  }
45
46
  });
46
47
  });
@@ -49,5 +50,12 @@ export function onUpdate(handle) {
49
50
  navigator.serviceWorker.addEventListener('controllerchange', () => {
50
51
  window.location.reload();
51
52
  });
52
- return () => { };
53
+ listenerSetUp = true;
54
+ }
55
+ export function onUpdate(handle) {
56
+ handlers.push(handle);
57
+ if (!listenerSetUp) {
58
+ setupSWListener();
59
+ }
60
+ handlers.push(handle);
53
61
  }
package/package.json CHANGED
@@ -1,6 +1,8 @@
1
1
  {
2
2
  "name": "sveltekit-cache-first",
3
- "version": "0.0.1",
3
+ "version": "0.0.3",
4
+ "repository": "github:isaxk/sveltekit-cache-first",
5
+ "license": "MIT",
4
6
  "scripts": {
5
7
  "dev": "vite dev",
6
8
  "build": "vite build && npm run prepack",