Skip to content
This repository was archived by the owner on Nov 9, 2023. It is now read-only.

Commit b426373

Browse files
committed
Allow writable store as subject in getResource
1 parent 251fe50 commit b426373

File tree

2 files changed

+53
-11
lines changed

2 files changed

+53
-11
lines changed

src/stores/getResource.test.ts

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
import { Store, urls } from '@tomic/lib';
22
import { describe, it, expect, beforeEach } from 'vitest';
33
import { getResource, initStore, store } from '~/index';
4-
import { get } from 'svelte/store';
4+
import { get, writable } from 'svelte/store';
55

66
const resource1Subject = 'https://resource1';
7+
const resource2Subject = 'https://resource2';
78

89
describe('getResource', () => {
910
beforeEach(() => {
@@ -44,4 +45,16 @@ describe('getResource', () => {
4445

4546
expect(resourceSecond.get(urls.properties.name)).toBe('Resource 1');
4647
});
48+
49+
it('should update when subject is writable and changes', async () => {
50+
const writableSubject = writable(resource1Subject);
51+
52+
const resource = getResource(writableSubject, { newResource: true });
53+
54+
expect(get(resource).getSubject()).toBe(resource1Subject);
55+
56+
writableSubject.set(resource2Subject);
57+
58+
expect(get(resource).getSubject()).toBe(resource2Subject);
59+
});
4760
});

src/stores/getResource.ts

Lines changed: 39 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,56 @@
1-
import { type FetchOpts, Resource } from '@tomic/lib';
1+
import { type FetchOpts, Resource, Store } from '@tomic/lib';
22

3-
import { type Readable, get, readable } from 'svelte/store';
3+
import { type Readable, get, readable, Subscriber } from 'svelte/store';
44
import { store } from './store';
55

6-
export const getResource = (
6+
const subscribeToADStore = (
7+
adStore: Store,
78
subject: string,
9+
set: Subscriber<Resource>,
10+
opts?: FetchOpts,
11+
) => {
12+
set(adStore.getResourceLoading(subject, opts));
13+
14+
const subscriber = (changedResource: Resource) => {
15+
set(changedResource);
16+
};
17+
18+
adStore.subscribe(subject, subscriber);
19+
20+
return () => {
21+
adStore.unsubscribe(subject, subscriber);
22+
};
23+
};
24+
25+
export const getResource = (
26+
subject: string | Readable<string>,
827
opts?: FetchOpts,
928
): Readable<Resource> => {
1029
const adStore = get(store);
1130

31+
const subjectValue = typeof subject === 'string' ? subject : get(subject);
32+
1233
// eslint-disable-next-line prefer-const
1334
let resource = readable<Resource>(
14-
adStore.getResourceLoading(subject, opts),
35+
adStore.getResourceLoading(subjectValue, opts),
1536
set => {
16-
set(adStore.getResourceLoading(subject, opts));
37+
if (typeof subject !== 'string') {
38+
let atomicUnsubscriber: () => void;
1739

18-
const subscriber = (changedResource: Resource) => {
19-
set(changedResource);
20-
};
40+
const subjectUnsubscriber = subject.subscribe(value => {
41+
atomicUnsubscriber?.();
2142

22-
adStore.subscribe(subject, subscriber);
43+
set(adStore.getResourceLoading(value, opts));
44+
atomicUnsubscriber = subscribeToADStore(adStore, value, set, opts);
45+
});
2346

24-
return () => adStore.unsubscribe(subject, subscriber);
47+
return () => {
48+
subjectUnsubscriber();
49+
atomicUnsubscriber?.();
50+
};
51+
} else {
52+
return subscribeToADStore(adStore, subject, set, opts);
53+
}
2554
},
2655
);
2756

0 commit comments

Comments
 (0)