astro-integration-pocketbase 1.0.0 → 1.2.0-next.1

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "astro-integration-pocketbase",
3
- "version": "1.0.0",
3
+ "version": "1.2.0-next.1",
4
4
  "license": "MIT",
5
5
  "author": "Luis Wolf <development@pawcode.de> (https://pawcode.de)",
6
6
  "homepage": "https://github.com/pawcoding/astro-integration-pocketbase",
@@ -2,6 +2,7 @@ import type { BaseIntegrationHooks } from "astro";
2
2
  import { EventSource } from "eventsource";
3
3
  import type { PocketBaseIntegrationOptions } from "../types/pocketbase-integration-options.type";
4
4
  import { getSuperuserToken } from "../utils/get-superuser-token";
5
+ import { mapCollectionsToWatch } from "../utils/map-collections-to-watch";
5
6
 
6
7
  export function refreshCollectionsRealtime(
7
8
  {
@@ -16,9 +17,11 @@ export function refreshCollectionsRealtime(
16
17
  }: Parameters<BaseIntegrationHooks["astro:server:setup"]>[0]
17
18
  ): EventSource | undefined {
18
19
  // Check if collections should be watched
19
- if (!collectionsToWatch || collectionsToWatch.length === 0) {
20
+ const collectionsMap = mapCollectionsToWatch(collectionsToWatch);
21
+ if (!collectionsMap) {
20
22
  return undefined;
21
23
  }
24
+ const remoteCollections = [...collectionsMap.keys()];
22
25
 
23
26
  // Check if content loader is used
24
27
  if (!refreshContent) {
@@ -65,7 +68,7 @@ export function refreshCollectionsRealtime(
65
68
  };
66
69
 
67
70
  // Add event listeners for all collections
68
- for (const collection of collectionsToWatch) {
71
+ for (const collection of remoteCollections) {
69
72
  eventSource.addEventListener(`${collection}/*`, async () => {
70
73
  // Do not refresh if the refresh is disabled
71
74
  if (!refreshEnabled) {
@@ -76,8 +79,10 @@ export function refreshCollectionsRealtime(
76
79
  logger.info(`Received update for ${collection}. Refreshing content...`);
77
80
  await refreshContent({
78
81
  loaders: ["pocketbase-loader"],
79
- // TODO: add context to refresh one or all collections
80
- context: {}
82
+ context: {
83
+ source: "astro-integration-pocketbase",
84
+ collection: collectionsMap.get(collection)
85
+ }
81
86
  });
82
87
  });
83
88
  }
@@ -106,7 +111,7 @@ export function refreshCollectionsRealtime(
106
111
  },
107
112
  body: JSON.stringify({
108
113
  clientId: clientId,
109
- subscriptions: collectionsToWatch.map((collection) => `${collection}/*`)
114
+ subscriptions: remoteCollections.map((collection) => `${collection}/*`)
110
115
  })
111
116
  });
112
117
 
@@ -121,7 +126,7 @@ export function refreshCollectionsRealtime(
121
126
  if (!wasConnectedOnce) {
122
127
  wasConnectedOnce = true;
123
128
  logger.info(
124
- `Subscribed to PocketBase realtime API. Waiting for updates on ${collectionsToWatch.join(
129
+ `Subscribed to PocketBase realtime API. Waiting for updates on ${remoteCollections.join(
125
130
  ", "
126
131
  )}.`
127
132
  );
@@ -26,8 +26,9 @@ export function handleRefreshCollections({
26
26
  logger.info("Refreshing content loaded by PocketBase loader");
27
27
  await refreshContent({
28
28
  loaders: ["pocketbase-loader"],
29
- // TODO: add context to refresh one or all collections
30
- context: {}
29
+ context: {
30
+ source: "astro-integration-pocketbase"
31
+ }
31
32
  });
32
33
 
33
34
  // Reset the loading state in the toolbar
@@ -23,6 +23,28 @@ export interface PocketBaseIntegrationOptions {
23
23
  /**
24
24
  * List of PocketBase collections to watch for changes.
25
25
  * When an entry in one of these collections changes, the content will be reloaded.
26
+ *
27
+ * Example:
28
+ * ```ts
29
+ * collectionsToWatch: ["users", "posts"]
30
+ * ```
31
+ *
32
+ * For advanced usage, you can specify a map where the key is the collection that is used to load the content.
33
+ * The value can be:
34
+ * - `true` to watch the collection itself for changes (base collection)
35
+ * - an array of strings to watch multiple collections for changes (view collection)
36
+ *
37
+ * These advanced options are especially useful when you're working with view collections.
38
+ * [View collections](https://pocketbase.io/docs/collections/#view-collection) don't emit events when their
39
+ * entries change, since they are based on other collections.
40
+ *
41
+ * Example:
42
+ * ```ts
43
+ * collectionsToWatch: {
44
+ * "users": true,
45
+ * "postings": ["posts", "comments"]
46
+ * }
47
+ * ```
26
48
  */
27
- collectionsToWatch?: Array<string>;
49
+ collectionsToWatch?: Array<string> | Record<string, true | Array<string>>;
28
50
  }
@@ -0,0 +1,53 @@
1
+ import type { PocketBaseIntegrationOptions } from "../types/pocketbase-integration-options.type";
2
+ import { pushToMapArray } from "./push-to-map-array";
3
+
4
+ /**
5
+ * Create a map of remote collections to watch.
6
+ * Each key in the map represents a remote collection to subscribe to.
7
+ * The value is an array of local collections that should be refreshed when an entry in the remote collection changes.
8
+ */
9
+ export function mapCollectionsToWatch(
10
+ collectionsToWatch: PocketBaseIntegrationOptions["collectionsToWatch"]
11
+ ): Map<string, Array<string>> | undefined {
12
+ // Check if collections should be watched
13
+ if (!collectionsToWatch) {
14
+ return;
15
+ }
16
+
17
+ // Check if collectionsToWatch is an array
18
+ if (Array.isArray(collectionsToWatch)) {
19
+ // Check if the array is empty
20
+ if (collectionsToWatch.length === 0) {
21
+ return;
22
+ }
23
+
24
+ // Create a map where each collection is watched by itself
25
+ return new Map(
26
+ collectionsToWatch.map((collection) => [collection, [collection]])
27
+ );
28
+ }
29
+
30
+ // Check if collectionsToWatch is an empty object
31
+ if (Object.keys(collectionsToWatch).length === 0) {
32
+ return;
33
+ }
34
+
35
+ // Map collections to watch
36
+ const collectionsMap = new Map<string, Array<string>>();
37
+ for (const localCollection in collectionsToWatch) {
38
+ const watch = collectionsToWatch[localCollection];
39
+
40
+ // Check if collection should be watched by itself
41
+ if (watch === true) {
42
+ pushToMapArray(collectionsMap, localCollection, localCollection);
43
+ continue;
44
+ }
45
+
46
+ // Collection should be watched by multiple collections
47
+ for (const remoteCollection of watch) {
48
+ pushToMapArray(collectionsMap, remoteCollection, localCollection);
49
+ }
50
+ }
51
+
52
+ return collectionsMap;
53
+ }
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Adds a value to an array in a map. If the key does not exist, it will be created.
3
+ */
4
+ export function pushToMapArray<TKey, TArray>(
5
+ map: Map<TKey, Array<TArray>>,
6
+ key: TKey,
7
+ value: TArray
8
+ ): void {
9
+ if (map.has(key)) {
10
+ map.get(key)!.push(value);
11
+ } else {
12
+ map.set(key, [value]);
13
+ }
14
+ }