Skip to content

Commit

Permalink
feat(composables): sharedRef with default value (#1591)
Browse files Browse the repository at this point in the history
  • Loading branch information
patzick authored Jul 8, 2021
1 parent d96204a commit cea3b15
Show file tree
Hide file tree
Showing 5 changed files with 84 additions and 6 deletions.
4 changes: 2 additions & 2 deletions api/composables.api.md
Original file line number Diff line number Diff line change
Expand Up @@ -648,9 +648,9 @@ export const useSalutations: (rootContext: ApplicationVueContext) => UseSalutati
// @beta
export const useSessionContext: (rootContext: ApplicationVueContext) => IUseSessionContext;

// @alpha
// @beta
export function useSharedState(rootContext: ApplicationVueContext): {
sharedRef: <T>(uniqueKey: string) => WritableComputedRef<T | null>;
sharedRef: <T>(uniqueKey: string, defaultValue?: T | undefined) => WritableComputedRef<T | null>;
preloadRef: (refObject: Ref<unknown>, callback: () => Promise<void>) => Promise<void>;
};

Expand Down
1 change: 1 addition & 0 deletions docs/landing/resources/api/composables.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
| [useBreadcrumbs(rootContext, params)](./composables.usebreadcrumbs.md) | <b><i>(BETA)</i></b> Composable for displaying and setting breadcrumbs for page. |
| [useCms(rootContext)](./composables.usecms.md) | <b><i>(BETA)</i></b> |
| [useProductAssociations(rootContext, product, association)](./composables.useproductassociations.md) | <b><i>(BETA)</i></b> Get product association entity. Options - [IUseProductAssociations](./composables.iuseproductassociations.md) |
| [useSharedState(rootContext)](./composables.usesharedstate.md) | <b><i>(BETA)</i></b> Replacement for Vuex. Composable, which enables you to use shared state in your application. State is shared both on server and client side. |

## Interfaces

Expand Down
30 changes: 30 additions & 0 deletions docs/landing/resources/api/composables.usesharedstate.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
<!-- Do not edit this file. It is automatically generated by API Documenter. -->

[Home](./index.md) &gt; [@shopware-pwa/composables](./composables.md) &gt; [useSharedState](./composables.usesharedstate.md)

## useSharedState() function

> This API is provided as a preview for developers and may change based on feedback that we receive. Do not use this API in a production environment.
>
Replacement for Vuex. Composable, which enables you to use shared state in your application. State is shared both on server and client side.

<b>Signature:</b>

```typescript
export declare function useSharedState(rootContext: ApplicationVueContext): {
sharedRef: <T>(uniqueKey: string, defaultValue?: T | undefined) => WritableComputedRef<T | null>;
preloadRef: (refObject: Ref<unknown>, callback: () => Promise<void>) => Promise<void>;
};
```

## Parameters

| Parameter | Type | Description |
| --- | --- | --- |
| rootContext | [ApplicationVueContext](./composables.applicationvuecontext.md) | |

<b>Returns:</b>

{ sharedRef: &lt;T&gt;(uniqueKey: string, defaultValue?: T \| undefined) =&gt; WritableComputedRef&lt;T \| null&gt;; preloadRef: (refObject: Ref&lt;unknown&gt;, callback: () =&gt; Promise&lt;void&gt;) =&gt; Promise&lt;void&gt;; }

37 changes: 37 additions & 0 deletions packages/composables/__tests__/useSharedState.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,43 @@ describe("Composables - useSharedState", () => {
"changed value"
);
});

it("should set default value for ref", () => {
const { sharedRef } = useSharedState(rootContextMock);
const result = sharedRef("unique-key", "some default value");
const result2 = sharedRef("unique-key");
expect(result.value).toEqual("some default value");
expect(result2.value).toEqual("some default value");
});

it("should set default value for first ref", () => {
const { sharedRef } = useSharedState(rootContextMock);
const result = sharedRef("unique-key");
const result2 = sharedRef("unique-key", "other default value");
expect(result.value).toEqual("other default value");
expect(result2.value).toEqual("other default value");
});

it("should not overwrite value with default value", () => {
rootContextMock.$sharedStore["unique-key"] = "test value";
const { sharedRef } = useSharedState(rootContextMock);
const result = sharedRef("unique-key", "some default value");
expect(result.value).toEqual("test value");
});

it("should not overwrite numeric value", () => {
rootContextMock.$sharedStore["unique-key"] = 0;
const { sharedRef } = useSharedState(rootContextMock);
const result = sharedRef("unique-key", "some default value");
expect(result.value).toEqual(0);
});

it("should not overwrite boolean value", () => {
rootContextMock.$sharedStore["unique-key"] = false;
const { sharedRef } = useSharedState(rootContextMock);
const result = sharedRef("unique-key", "some default value");
expect(result.value).toEqual(false);
});
});

describe("preloadRef", () => {
Expand Down
18 changes: 14 additions & 4 deletions packages/composables/src/logic/useSharedState.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ const localSharedState: {
* Replacement for Vuex. Composable, which enables you to use shared state in your application.
* State is shared both on server and client side.
*
* @alpha
* @beta
*/
export function useSharedState(rootContext: ApplicationVueContext) {
const { sharedStore, isServer } = getApplicationContext(
Expand All @@ -31,9 +31,12 @@ export function useSharedState(rootContext: ApplicationVueContext) {
* `uniqueKey` is used to identify value after sending it from the server.
* You can use the same key to reach this value, but setting the same keys on different values will cause values override.
*
* @alpha
* @beta
*/
function sharedRef<T>(uniqueKey: string): WritableComputedRef<T | null> {
function sharedRef<T>(
uniqueKey: string,
defaultValue?: T
): WritableComputedRef<T | null> {
if (!isServer && !localSharedState[uniqueKey]) {
localSharedState[uniqueKey] = ref(sharedStore[uniqueKey]);
}
Expand All @@ -42,9 +45,16 @@ export function useSharedState(rootContext: ApplicationVueContext) {
? toRef(sharedStore, uniqueKey)
: localSharedState[uniqueKey];

if (
(sharedRef.value === null || typeof sharedRef.value === "undefined") &&
defaultValue
) {
sharedRef.value = defaultValue;
}

return computed({
get: () => {
return sharedRef.value || null;
return sharedRef.value ?? null;
},
set: (val) => {
sharedRef.value = val;
Expand Down

1 comment on commit cea3b15

@vercel
Copy link

@vercel vercel bot commented on cea3b15 Jul 8, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.