@rainlanguage/ui-components 0.0.1-alpha.226 → 0.0.1-alpha.228
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/dist/__fixtures__/settings.yaml +1 -1
- package/dist/components/deployment/DeploymentSteps.svelte +3 -3
- package/dist/components/deployment/DeploymentTile.svelte +3 -3
- package/dist/components/deployment/InvalidOrdersSection.svelte +1 -1
- package/dist/components/deployment/ValidOrdersSection.svelte +3 -3
- package/dist/components/input/InputRainlangUrl.svelte +40 -0
- package/dist/components/input/InputRainlangUrl.svelte.d.ts +16 -0
- package/dist/index.d.ts +7 -7
- package/dist/index.js +6 -6
- package/dist/providers/dotrainRainlang/DotrainRainlangProvider.svelte +8 -0
- package/dist/providers/dotrainRainlang/DotrainRainlangProvider.svelte.d.ts +24 -0
- package/dist/providers/dotrainRainlang/context.d.ts +9 -0
- package/dist/providers/{dotrainRegistry → dotrainRainlang}/context.js +12 -12
- package/dist/providers/dotrainRainlang/useDotrainRainlang.d.ts +5 -0
- package/dist/providers/dotrainRainlang/useDotrainRainlang.js +35 -0
- package/dist/providers/rainlang/RainlangManager.d.ts +65 -0
- package/dist/providers/rainlang/RainlangManager.js +133 -0
- package/dist/providers/rainlang/RainlangProvider.svelte +6 -0
- package/dist/providers/rainlang/RainlangProvider.svelte.d.ts +21 -0
- package/dist/providers/rainlang/context.d.ts +10 -0
- package/dist/providers/rainlang/context.js +46 -0
- package/dist/providers/rainlang/useRainlang.d.ts +7 -0
- package/dist/providers/rainlang/useRainlang.js +29 -0
- package/dist/services/handleShareChoices.d.ts +1 -1
- package/dist/services/handleShareChoices.js +2 -2
- package/dist/services/index.d.ts +3 -3
- package/dist/services/index.js +2 -2
- package/dist/services/loadRainlangUrl.d.ts +2 -0
- package/dist/services/loadRainlangUrl.js +22 -0
- package/dist/services/{registry.d.ts → rainlang.d.ts} +10 -10
- package/dist/services/{registry.js → rainlang.js} +15 -15
- package/package.json +2 -2
- package/dist/components/input/InputRegistryUrl.svelte +0 -40
- package/dist/components/input/InputRegistryUrl.svelte.d.ts +0 -16
- package/dist/providers/dotrainRegistry/DotrainRegistryProvider.svelte +0 -8
- package/dist/providers/dotrainRegistry/DotrainRegistryProvider.svelte.d.ts +0 -24
- package/dist/providers/dotrainRegistry/context.d.ts +0 -9
- package/dist/providers/dotrainRegistry/useDotrainRegistry.d.ts +0 -5
- package/dist/providers/dotrainRegistry/useDotrainRegistry.js +0 -35
- package/dist/providers/registry/RegistryManager.d.ts +0 -65
- package/dist/providers/registry/RegistryManager.js +0 -133
- package/dist/providers/registry/RegistryProvider.svelte +0 -6
- package/dist/providers/registry/RegistryProvider.svelte.d.ts +0 -21
- package/dist/providers/registry/context.d.ts +0 -10
- package/dist/providers/registry/context.js +0 -46
- package/dist/providers/registry/useRegistry.d.ts +0 -7
- package/dist/providers/registry/useRegistry.js +0 -29
- package/dist/services/loadRegistryUrl.d.ts +0 -2
- package/dist/services/loadRegistryUrl.js +0 -22
|
@@ -19,7 +19,7 @@ import DeploymentSectionHeader from "./DeploymentSectionHeader.svelte";
|
|
|
19
19
|
import { useGui } from "../../hooks/useGui";
|
|
20
20
|
import { fade } from "svelte/transition";
|
|
21
21
|
import ShareChoicesButton from "./ShareChoicesButton.svelte";
|
|
22
|
-
import {
|
|
22
|
+
import { useRainlang } from "../../providers/rainlang/useRainlang";
|
|
23
23
|
import { useRaindexClient } from "../../hooks/useRaindexClient";
|
|
24
24
|
export let deployment;
|
|
25
25
|
export let orderDetail;
|
|
@@ -39,7 +39,7 @@ let selectTokens = void 0;
|
|
|
39
39
|
let checkingDeployment = false;
|
|
40
40
|
let tokenBalances = /* @__PURE__ */ new Map();
|
|
41
41
|
const gui = useGui();
|
|
42
|
-
const
|
|
42
|
+
const rainlang = useRainlang();
|
|
43
43
|
const raindexClient = useRaindexClient();
|
|
44
44
|
let deploymentStepsError = DeploymentStepsError.error;
|
|
45
45
|
onMount(async () => {
|
|
@@ -93,7 +93,7 @@ function updateFields() {
|
|
|
93
93
|
}
|
|
94
94
|
}
|
|
95
95
|
async function _handleShareChoices() {
|
|
96
|
-
await handleShareChoices(gui,
|
|
96
|
+
await handleShareChoices(gui, rainlang.getCurrentRainlang());
|
|
97
97
|
}
|
|
98
98
|
async function fetchTokenBalance(tokenInfo) {
|
|
99
99
|
if (!$account) return;
|
|
@@ -4,14 +4,14 @@ export let orderName;
|
|
|
4
4
|
export let key;
|
|
5
5
|
export let name;
|
|
6
6
|
export let description;
|
|
7
|
-
let
|
|
7
|
+
let customRainlangParam = "";
|
|
8
8
|
onMount(async () => {
|
|
9
|
-
|
|
9
|
+
customRainlangParam = $page.url.searchParams.get("rainlang") ? `?rainlang=${$page.url.searchParams.get("rainlang")}` : "";
|
|
10
10
|
});
|
|
11
11
|
</script>
|
|
12
12
|
|
|
13
13
|
<a
|
|
14
|
-
href={`/deploy/${orderName}/${key}${
|
|
14
|
+
href={`/deploy/${orderName}/${key}${customRainlangParam}`}
|
|
15
15
|
class="flex h-full w-full max-w-sm cursor-pointer flex-col gap-y-4 rounded-3xl border border-gray-200 bg-white p-4 text-left hover:bg-gray-100 dark:border-gray-700 dark:bg-gray-800 dark:hover:bg-gray-700"
|
|
16
16
|
>
|
|
17
17
|
<h1 class="text-2xl font-semibold text-gray-900 dark:text-white">{name}</h1>
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
class="flex flex-col gap-4 rounded-xl bg-red-100 p-6 dark:bg-red-900"
|
|
6
6
|
data-testid="invalid-orders"
|
|
7
7
|
>
|
|
8
|
-
<h2 class="text-xl font-semibold text-gray-900 dark:text-white">Invalid orders in
|
|
8
|
+
<h2 class="text-xl font-semibold text-gray-900 dark:text-white">Invalid orders in rainlang</h2>
|
|
9
9
|
<div class="flex flex-col gap-2">
|
|
10
10
|
{#each ordersWithErrors as order}
|
|
11
11
|
<div class="flex flex-col gap-1">
|
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
<script>import { onMount } from "svelte";
|
|
2
2
|
import { page } from "$app/stores";
|
|
3
3
|
export let orders;
|
|
4
|
-
let
|
|
4
|
+
let customRainlangParam = "";
|
|
5
5
|
onMount(async () => {
|
|
6
|
-
|
|
6
|
+
customRainlangParam = $page.url.searchParams.get("rainlang") ? `?rainlang=${$page.url.searchParams.get("rainlang")}` : "";
|
|
7
7
|
});
|
|
8
8
|
</script>
|
|
9
9
|
|
|
10
10
|
<div class="grid grid-cols-1 gap-6 md:grid-cols-2 lg:grid-cols-3" data-testid="valid-orders">
|
|
11
11
|
{#each orders as order}
|
|
12
12
|
<a
|
|
13
|
-
href={`/deploy/${order.name}${
|
|
13
|
+
href={`/deploy/${order.name}${customRainlangParam}`}
|
|
14
14
|
data-testid="order-short-tile"
|
|
15
15
|
class="flex flex-col gap-y-2 rounded-xl border border-gray-200 p-4 hover:bg-gray-50 dark:border-gray-800 dark:hover:bg-gray-900"
|
|
16
16
|
>
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
<script>import { Button, Input } from "flowbite-svelte";
|
|
2
|
+
import { useRainlang } from "../../providers/rainlang/useRainlang";
|
|
3
|
+
import { loadRainlangUrl } from "../../services/loadRainlangUrl";
|
|
4
|
+
const rainlang = useRainlang();
|
|
5
|
+
let newRainlangUrl = rainlang.getCurrentRainlang();
|
|
6
|
+
let error = null;
|
|
7
|
+
let loading = false;
|
|
8
|
+
async function handleClick() {
|
|
9
|
+
loading = true;
|
|
10
|
+
error = null;
|
|
11
|
+
try {
|
|
12
|
+
if (!rainlang) {
|
|
13
|
+
throw new Error("Rainlang manager not yet available.");
|
|
14
|
+
}
|
|
15
|
+
await loadRainlangUrl(newRainlangUrl, rainlang);
|
|
16
|
+
} catch (err) {
|
|
17
|
+
error = err instanceof Error ? err.message : "Unknown error";
|
|
18
|
+
}
|
|
19
|
+
loading = false;
|
|
20
|
+
}
|
|
21
|
+
</script>
|
|
22
|
+
|
|
23
|
+
<div class="flex w-full flex-col items-end gap-2">
|
|
24
|
+
<div class="flex w-full items-start gap-4" data-testid="rainlang-input">
|
|
25
|
+
<Input
|
|
26
|
+
id="order-url"
|
|
27
|
+
type="url"
|
|
28
|
+
placeholder="Enter URL to raw order rainlang file"
|
|
29
|
+
bind:value={newRainlangUrl}
|
|
30
|
+
/>
|
|
31
|
+
<Button class="w-36 text-nowrap" on:click={handleClick} disabled={loading}>
|
|
32
|
+
{loading ? 'Loading rainlang...' : 'Load rainlang URL'}
|
|
33
|
+
</Button>
|
|
34
|
+
</div>
|
|
35
|
+
<div class="h-4">
|
|
36
|
+
{#if error}
|
|
37
|
+
<p data-testid="rainlang-error" class="text-red-500">{error}</p>
|
|
38
|
+
{/if}
|
|
39
|
+
</div>
|
|
40
|
+
</div>
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { SvelteComponent } from "svelte";
|
|
2
|
+
declare const __propDef: {
|
|
3
|
+
props: Record<string, never>;
|
|
4
|
+
events: {
|
|
5
|
+
[evt: string]: CustomEvent<any>;
|
|
6
|
+
};
|
|
7
|
+
slots: {};
|
|
8
|
+
exports?: {} | undefined;
|
|
9
|
+
bindings?: string | undefined;
|
|
10
|
+
};
|
|
11
|
+
export type InputRainlangUrlProps = typeof __propDef.props;
|
|
12
|
+
export type InputRainlangUrlEvents = typeof __propDef.events;
|
|
13
|
+
export type InputRainlangUrlSlots = typeof __propDef.slots;
|
|
14
|
+
export default class InputRainlangUrl extends SvelteComponent<InputRainlangUrlProps, InputRainlangUrlEvents, InputRainlangUrlSlots> {
|
|
15
|
+
}
|
|
16
|
+
export {};
|
package/dist/index.d.ts
CHANGED
|
@@ -66,7 +66,7 @@ export { default as WalletConnect } from './components/wallet/WalletConnect.svel
|
|
|
66
66
|
export { default as DisclaimerModal } from './components/deployment/DisclaimerModal.svelte';
|
|
67
67
|
export { default as InvalidOrdersSection } from './components/deployment/InvalidOrdersSection.svelte';
|
|
68
68
|
export { default as ValidOrdersSection } from './components/deployment/ValidOrdersSection.svelte';
|
|
69
|
-
export { default as
|
|
69
|
+
export { default as InputRainlangUrl } from './components/input/InputRainlangUrl.svelte';
|
|
70
70
|
export { default as TransactionList } from './components/transactions/TransactionList.svelte';
|
|
71
71
|
export { default as FixedBottomTransaction } from './components/transactions/FixedBottomTransaction.svelte';
|
|
72
72
|
export { default as LocalDbStatusCard } from './components/LocalDbStatusCard.svelte';
|
|
@@ -77,7 +77,7 @@ export { TransactionStatusMessage, TransactionStoreErrorMessage, type Transactio
|
|
|
77
77
|
export type { VaultActionModalProps, QuoteDebugModalHandler, DebugTradeModalHandler, DisclaimerModalProps, TransactionConfirmationProps, HandleTransactionConfirmationModal } from './types/modal';
|
|
78
78
|
export type { ValidOrderDetail, InvalidOrderDetail } from './types/order.ts';
|
|
79
79
|
export type { ToastProps } from './types/toast';
|
|
80
|
-
export type {
|
|
80
|
+
export type { DotrainRainlangContext } from './providers/dotrainRainlang/context';
|
|
81
81
|
export { createResolvableQuery, createResolvableInfiniteQuery } from './__mocks__/queries';
|
|
82
82
|
export { formatTimestampSecondsAsLocal, timestampSecondsToUTCTimestamp, promiseTimeout } from './services/time';
|
|
83
83
|
export { bigintStringToHex, HEX_INPUT_REGEX } from './utils/hex';
|
|
@@ -95,20 +95,20 @@ export { default as logoDark } from './assets/logo-dark.svg';
|
|
|
95
95
|
export { default as GuiProvider } from './providers/GuiProvider.svelte';
|
|
96
96
|
export { default as RaindexClientProvider } from './providers/RaindexClientProvider.svelte';
|
|
97
97
|
export { default as WalletProvider } from './providers/wallet/WalletProvider.svelte';
|
|
98
|
-
export { default as
|
|
98
|
+
export { default as RainlangProvider } from './providers/rainlang/RainlangProvider.svelte';
|
|
99
99
|
export { default as ToastProvider } from './providers/toasts/ToastProvider.svelte';
|
|
100
100
|
export { default as TransactionProvider } from './providers/transactions/TransactionProvider.svelte';
|
|
101
101
|
export { default as LocalDbProvider } from './providers/LocalDbProvider.svelte';
|
|
102
|
-
export { default as
|
|
102
|
+
export { default as DotrainRainlangProvider } from './providers/dotrainRainlang/DotrainRainlangProvider.svelte';
|
|
103
103
|
export { useGui } from './hooks/useGui';
|
|
104
104
|
export { useRaindexClient, RAINDEX_CLIENT_CONTEXT_KEY } from './hooks/useRaindexClient';
|
|
105
105
|
export { useLocalDb } from './hooks/useLocalDb';
|
|
106
106
|
export { useAccount } from './providers/wallet/useAccount';
|
|
107
|
-
export {
|
|
107
|
+
export { useRainlang } from './providers/rainlang/useRainlang';
|
|
108
108
|
export { useToasts } from './providers/toasts/useToasts';
|
|
109
109
|
export { useTransactions } from './providers/transactions/useTransactions';
|
|
110
|
-
export {
|
|
111
|
-
export {
|
|
110
|
+
export { useDotrainRainlang } from './providers/dotrainRainlang/useDotrainRainlang';
|
|
111
|
+
export { RainlangManager } from './providers/rainlang/RainlangManager';
|
|
112
112
|
export { TransactionStore } from './models/Transaction';
|
|
113
113
|
export { TransactionManager } from './providers/transactions/TransactionManager';
|
|
114
114
|
export { mockPageStore } from './__mocks__/stores';
|
package/dist/index.js
CHANGED
|
@@ -67,7 +67,7 @@ export { default as WalletConnect } from './components/wallet/WalletConnect.svel
|
|
|
67
67
|
export { default as DisclaimerModal } from './components/deployment/DisclaimerModal.svelte';
|
|
68
68
|
export { default as InvalidOrdersSection } from './components/deployment/InvalidOrdersSection.svelte';
|
|
69
69
|
export { default as ValidOrdersSection } from './components/deployment/ValidOrdersSection.svelte';
|
|
70
|
-
export { default as
|
|
70
|
+
export { default as InputRainlangUrl } from './components/input/InputRainlangUrl.svelte';
|
|
71
71
|
export { default as TransactionList } from './components/transactions/TransactionList.svelte';
|
|
72
72
|
export { default as FixedBottomTransaction } from './components/transactions/FixedBottomTransaction.svelte';
|
|
73
73
|
export { default as LocalDbStatusCard } from './components/LocalDbStatusCard.svelte';
|
|
@@ -96,22 +96,22 @@ export { default as logoDark } from './assets/logo-dark.svg';
|
|
|
96
96
|
export { default as GuiProvider } from './providers/GuiProvider.svelte';
|
|
97
97
|
export { default as RaindexClientProvider } from './providers/RaindexClientProvider.svelte';
|
|
98
98
|
export { default as WalletProvider } from './providers/wallet/WalletProvider.svelte';
|
|
99
|
-
export { default as
|
|
99
|
+
export { default as RainlangProvider } from './providers/rainlang/RainlangProvider.svelte';
|
|
100
100
|
export { default as ToastProvider } from './providers/toasts/ToastProvider.svelte';
|
|
101
101
|
export { default as TransactionProvider } from './providers/transactions/TransactionProvider.svelte';
|
|
102
102
|
export { default as LocalDbProvider } from './providers/LocalDbProvider.svelte';
|
|
103
|
-
export { default as
|
|
103
|
+
export { default as DotrainRainlangProvider } from './providers/dotrainRainlang/DotrainRainlangProvider.svelte';
|
|
104
104
|
// Hooks
|
|
105
105
|
export { useGui } from './hooks/useGui';
|
|
106
106
|
export { useRaindexClient, RAINDEX_CLIENT_CONTEXT_KEY } from './hooks/useRaindexClient';
|
|
107
107
|
export { useLocalDb } from './hooks/useLocalDb';
|
|
108
108
|
export { useAccount } from './providers/wallet/useAccount';
|
|
109
|
-
export {
|
|
109
|
+
export { useRainlang } from './providers/rainlang/useRainlang';
|
|
110
110
|
export { useToasts } from './providers/toasts/useToasts';
|
|
111
111
|
export { useTransactions } from './providers/transactions/useTransactions';
|
|
112
|
-
export {
|
|
112
|
+
export { useDotrainRainlang } from './providers/dotrainRainlang/useDotrainRainlang';
|
|
113
113
|
// Classes
|
|
114
|
-
export {
|
|
114
|
+
export { RainlangManager } from './providers/rainlang/RainlangManager';
|
|
115
115
|
export { TransactionStore } from './models/Transaction';
|
|
116
116
|
export { TransactionManager } from './providers/transactions/TransactionManager';
|
|
117
117
|
// Mocks
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { SvelteComponent } from "svelte";
|
|
2
|
+
import type { DotrainRainlang } from '@rainlanguage/orderbook';
|
|
3
|
+
import type { RainlangManager } from '../rainlang/RainlangManager';
|
|
4
|
+
declare const __propDef: {
|
|
5
|
+
props: {
|
|
6
|
+
rainlang?: DotrainRainlang | null;
|
|
7
|
+
error: string | undefined;
|
|
8
|
+
manager: RainlangManager;
|
|
9
|
+
};
|
|
10
|
+
events: {
|
|
11
|
+
[evt: string]: CustomEvent<any>;
|
|
12
|
+
};
|
|
13
|
+
slots: {
|
|
14
|
+
default: {};
|
|
15
|
+
};
|
|
16
|
+
exports?: {} | undefined;
|
|
17
|
+
bindings?: string | undefined;
|
|
18
|
+
};
|
|
19
|
+
export type DotrainRainlangProviderProps = typeof __propDef.props;
|
|
20
|
+
export type DotrainRainlangProviderEvents = typeof __propDef.events;
|
|
21
|
+
export type DotrainRainlangProviderSlots = typeof __propDef.slots;
|
|
22
|
+
export default class DotrainRainlangProvider extends SvelteComponent<DotrainRainlangProviderProps, DotrainRainlangProviderEvents, DotrainRainlangProviderSlots> {
|
|
23
|
+
}
|
|
24
|
+
export {};
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { DotrainRainlang } from '@rainlanguage/orderbook';
|
|
2
|
+
import type { RainlangManager } from '../rainlang/RainlangManager';
|
|
3
|
+
export type DotrainRainlangContext = {
|
|
4
|
+
rainlang: DotrainRainlang | null;
|
|
5
|
+
error?: string;
|
|
6
|
+
manager: RainlangManager;
|
|
7
|
+
};
|
|
8
|
+
export declare const setDotrainRainlangContext: (context: DotrainRainlangContext) => void;
|
|
9
|
+
export declare const getDotrainRainlangContext: () => DotrainRainlangContext;
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import { getContext, setContext } from 'svelte';
|
|
2
|
-
const
|
|
3
|
-
export const
|
|
4
|
-
setContext(
|
|
2
|
+
const DOTRAIN_RAINLANG_CONTEXT_KEY = 'dotrain-rainlang-context';
|
|
3
|
+
export const setDotrainRainlangContext = (context) => {
|
|
4
|
+
setContext(DOTRAIN_RAINLANG_CONTEXT_KEY, context);
|
|
5
5
|
};
|
|
6
|
-
export const
|
|
7
|
-
const ctx = getContext(
|
|
6
|
+
export const getDotrainRainlangContext = () => {
|
|
7
|
+
const ctx = getContext(DOTRAIN_RAINLANG_CONTEXT_KEY);
|
|
8
8
|
if (!ctx) {
|
|
9
|
-
throw new Error('Dotrain
|
|
9
|
+
throw new Error('Dotrain rainlang context not found. Did you forget to wrap your app in DotrainRainlangProvider?');
|
|
10
10
|
}
|
|
11
11
|
return ctx;
|
|
12
12
|
};
|
|
@@ -16,25 +16,25 @@ if (import.meta.vitest) {
|
|
|
16
16
|
...(await importOriginal()),
|
|
17
17
|
getContext: vi.fn()
|
|
18
18
|
}));
|
|
19
|
-
describe('
|
|
19
|
+
describe('getDotrainRainlangContext', () => {
|
|
20
20
|
const mockGetContext = vi.mocked(getContext);
|
|
21
21
|
beforeEach(() => {
|
|
22
22
|
mockGetContext.mockReset();
|
|
23
23
|
});
|
|
24
24
|
it('should return the context when it exists', () => {
|
|
25
|
-
const mockCtx = {
|
|
25
|
+
const mockCtx = { rainlang: null, manager: {} };
|
|
26
26
|
mockGetContext.mockImplementation((key) => {
|
|
27
|
-
if (key ===
|
|
27
|
+
if (key === DOTRAIN_RAINLANG_CONTEXT_KEY)
|
|
28
28
|
return mockCtx;
|
|
29
29
|
return undefined;
|
|
30
30
|
});
|
|
31
|
-
const result =
|
|
32
|
-
expect(mockGetContext).toHaveBeenCalledWith(
|
|
31
|
+
const result = getDotrainRainlangContext();
|
|
32
|
+
expect(mockGetContext).toHaveBeenCalledWith(DOTRAIN_RAINLANG_CONTEXT_KEY);
|
|
33
33
|
expect(result).toEqual(mockCtx);
|
|
34
34
|
});
|
|
35
35
|
it('should throw an error when context is not set', () => {
|
|
36
36
|
mockGetContext.mockReturnValue(undefined);
|
|
37
|
-
expect(() =>
|
|
37
|
+
expect(() => getDotrainRainlangContext()).toThrow('Dotrain rainlang context not found. Did you forget to wrap your app in DotrainRainlangProvider?');
|
|
38
38
|
});
|
|
39
39
|
});
|
|
40
40
|
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { getDotrainRainlangContext } from './context';
|
|
2
|
+
/**
|
|
3
|
+
* Hook to access the current Dotrain rainlang context.
|
|
4
|
+
*/
|
|
5
|
+
export function useDotrainRainlang() {
|
|
6
|
+
return getDotrainRainlangContext();
|
|
7
|
+
}
|
|
8
|
+
if (import.meta.vitest) {
|
|
9
|
+
const { describe, it, expect, vi, beforeEach } = import.meta.vitest;
|
|
10
|
+
vi.mock('./context', () => ({
|
|
11
|
+
getDotrainRainlangContext: vi.fn()
|
|
12
|
+
}));
|
|
13
|
+
describe('useDotrainRainlang', () => {
|
|
14
|
+
const mockGetContext = vi.mocked(getDotrainRainlangContext);
|
|
15
|
+
beforeEach(() => {
|
|
16
|
+
mockGetContext.mockReset();
|
|
17
|
+
});
|
|
18
|
+
it('should return the rainlang context', () => {
|
|
19
|
+
const mockContext = {
|
|
20
|
+
rainlang: null,
|
|
21
|
+
manager: {
|
|
22
|
+
getCurrentRainlang: vi.fn().mockReturnValue(''),
|
|
23
|
+
setRainlang: vi.fn(),
|
|
24
|
+
resetToDefault: vi.fn(),
|
|
25
|
+
updateUrlWithRainlang: vi.fn(),
|
|
26
|
+
isCustomRainlang: vi.fn().mockReturnValue(false)
|
|
27
|
+
}
|
|
28
|
+
};
|
|
29
|
+
mockGetContext.mockReturnValue(mockContext);
|
|
30
|
+
const result = useDotrainRainlang();
|
|
31
|
+
expect(mockGetContext).toHaveBeenCalled();
|
|
32
|
+
expect(result).toEqual(mockContext);
|
|
33
|
+
});
|
|
34
|
+
});
|
|
35
|
+
}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Manages rainlang URL settings, persisting values in localStorage and URL parameters
|
|
3
|
+
*/
|
|
4
|
+
export declare class RainlangManager {
|
|
5
|
+
/** The default rainlang URL to fall back to */
|
|
6
|
+
private defaultRainlang;
|
|
7
|
+
/** The currently selected rainlang URL */
|
|
8
|
+
private currentRainlang;
|
|
9
|
+
/** Key used for localStorage and URL parameters */
|
|
10
|
+
private static STORAGE_KEY;
|
|
11
|
+
/**
|
|
12
|
+
* Create a new RainlangManager
|
|
13
|
+
* @param defaultRainlang The default rainlang URL to use.
|
|
14
|
+
*/
|
|
15
|
+
constructor(defaultRainlang: string);
|
|
16
|
+
/**
|
|
17
|
+
* Initialize rainlang from URL param or local storage
|
|
18
|
+
* @returns The rainlang URL to use
|
|
19
|
+
*/
|
|
20
|
+
private loadRainlangFromStorageOrUrl;
|
|
21
|
+
/**
|
|
22
|
+
* Get the rainlang from the URL param
|
|
23
|
+
* @returns The rainlang value from URL or null if not present
|
|
24
|
+
* @throws Error if URL parsing fails
|
|
25
|
+
*/
|
|
26
|
+
private getRainlangParamFromUrl;
|
|
27
|
+
/**
|
|
28
|
+
* Save the rainlang to local storage
|
|
29
|
+
* @param rainlang The rainlang URL to save
|
|
30
|
+
* @throws Error if localStorage is not available
|
|
31
|
+
*/
|
|
32
|
+
private setRainlangToLocalStorage;
|
|
33
|
+
/**
|
|
34
|
+
* Retrieve the rainlang from local storage
|
|
35
|
+
* @returns The stored rainlang URL or null if not found
|
|
36
|
+
* @throws Error if localStorage is not available
|
|
37
|
+
*/
|
|
38
|
+
private getRainlangFromLocalStorage;
|
|
39
|
+
/**
|
|
40
|
+
* Get the currently active rainlang
|
|
41
|
+
* @returns The current rainlang URL, falling back to default if not set
|
|
42
|
+
*/
|
|
43
|
+
getCurrentRainlang(): string;
|
|
44
|
+
/**
|
|
45
|
+
* Set the rainlang and update both localStorage and URL
|
|
46
|
+
* @param rainlang The new rainlang URL to set
|
|
47
|
+
*/
|
|
48
|
+
setRainlang(rainlang: string): void;
|
|
49
|
+
/**
|
|
50
|
+
* Reset to the default rainlang, clearing both localStorage and URL param
|
|
51
|
+
* @throws Error if localStorage is not available
|
|
52
|
+
*/
|
|
53
|
+
resetToDefault(): void;
|
|
54
|
+
/**
|
|
55
|
+
* Update the URL param to reflect the current or specified rainlang
|
|
56
|
+
* @param value The rainlang value to set in URL, defaults to current rainlang
|
|
57
|
+
* @throws Error if URL manipulation fails
|
|
58
|
+
*/
|
|
59
|
+
updateUrlWithRainlang(value?: string | null): void;
|
|
60
|
+
/**
|
|
61
|
+
* Check if the current rainlang is custom (different from the default)
|
|
62
|
+
* @returns True if using a non-default rainlang
|
|
63
|
+
*/
|
|
64
|
+
isCustomRainlang(): boolean;
|
|
65
|
+
}
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Manages rainlang URL settings, persisting values in localStorage and URL parameters
|
|
3
|
+
*/
|
|
4
|
+
export class RainlangManager {
|
|
5
|
+
/** The default rainlang URL to fall back to */
|
|
6
|
+
defaultRainlang;
|
|
7
|
+
/** The currently selected rainlang URL */
|
|
8
|
+
currentRainlang;
|
|
9
|
+
/** Key used for localStorage and URL parameters */
|
|
10
|
+
static STORAGE_KEY = 'rainlang';
|
|
11
|
+
/**
|
|
12
|
+
* Create a new RainlangManager
|
|
13
|
+
* @param defaultRainlang The default rainlang URL to use.
|
|
14
|
+
*/
|
|
15
|
+
constructor(defaultRainlang) {
|
|
16
|
+
this.defaultRainlang = defaultRainlang;
|
|
17
|
+
this.currentRainlang = this.loadRainlangFromStorageOrUrl();
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Initialize rainlang from URL param or local storage
|
|
21
|
+
* @returns The rainlang URL to use
|
|
22
|
+
*/
|
|
23
|
+
loadRainlangFromStorageOrUrl() {
|
|
24
|
+
const urlParam = this.getRainlangParamFromUrl();
|
|
25
|
+
if (urlParam) {
|
|
26
|
+
this.setRainlangToLocalStorage(urlParam);
|
|
27
|
+
return urlParam;
|
|
28
|
+
}
|
|
29
|
+
return this.getRainlangFromLocalStorage() ?? this.defaultRainlang;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Get the rainlang from the URL param
|
|
33
|
+
* @returns The rainlang value from URL or null if not present
|
|
34
|
+
* @throws Error if URL parsing fails
|
|
35
|
+
*/
|
|
36
|
+
getRainlangParamFromUrl() {
|
|
37
|
+
try {
|
|
38
|
+
return new URL(window.location.href).searchParams.get(RainlangManager.STORAGE_KEY);
|
|
39
|
+
}
|
|
40
|
+
catch (error) {
|
|
41
|
+
throw new Error('Failed to get rainlang parameter: ' +
|
|
42
|
+
(error instanceof Error ? error.message : String(error)));
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Save the rainlang to local storage
|
|
47
|
+
* @param rainlang The rainlang URL to save
|
|
48
|
+
* @throws Error if localStorage is not available
|
|
49
|
+
*/
|
|
50
|
+
setRainlangToLocalStorage(rainlang) {
|
|
51
|
+
try {
|
|
52
|
+
localStorage.setItem(RainlangManager.STORAGE_KEY, rainlang);
|
|
53
|
+
}
|
|
54
|
+
catch (error) {
|
|
55
|
+
throw new Error('Failed to save to localStorage: ' +
|
|
56
|
+
(error instanceof Error ? error.message : String(error)));
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Retrieve the rainlang from local storage
|
|
61
|
+
* @returns The stored rainlang URL or null if not found
|
|
62
|
+
* @throws Error if localStorage is not available
|
|
63
|
+
*/
|
|
64
|
+
getRainlangFromLocalStorage() {
|
|
65
|
+
try {
|
|
66
|
+
return localStorage.getItem(RainlangManager.STORAGE_KEY);
|
|
67
|
+
}
|
|
68
|
+
catch (error) {
|
|
69
|
+
throw new Error('Failed to access localStorage: ' + (error instanceof Error ? error.message : String(error)));
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Get the currently active rainlang
|
|
74
|
+
* @returns The current rainlang URL, falling back to default if not set
|
|
75
|
+
*/
|
|
76
|
+
getCurrentRainlang() {
|
|
77
|
+
return this.currentRainlang ?? this.defaultRainlang;
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Set the rainlang and update both localStorage and URL
|
|
81
|
+
* @param rainlang The new rainlang URL to set
|
|
82
|
+
*/
|
|
83
|
+
setRainlang(rainlang) {
|
|
84
|
+
this.currentRainlang = rainlang;
|
|
85
|
+
this.setRainlangToLocalStorage(rainlang);
|
|
86
|
+
this.updateUrlWithRainlang();
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* Reset to the default rainlang, clearing both localStorage and URL param
|
|
90
|
+
* @throws Error if localStorage is not available
|
|
91
|
+
*/
|
|
92
|
+
resetToDefault() {
|
|
93
|
+
this.currentRainlang = this.defaultRainlang;
|
|
94
|
+
try {
|
|
95
|
+
localStorage.removeItem(RainlangManager.STORAGE_KEY);
|
|
96
|
+
}
|
|
97
|
+
catch (error) {
|
|
98
|
+
throw new Error('Failed to clear rainlang from localStorage: ' +
|
|
99
|
+
(error instanceof Error ? error.message : String(error)));
|
|
100
|
+
}
|
|
101
|
+
this.updateUrlWithRainlang(null);
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* Update the URL param to reflect the current or specified rainlang
|
|
105
|
+
* @param value The rainlang value to set in URL, defaults to current rainlang
|
|
106
|
+
* @throws Error if URL manipulation fails
|
|
107
|
+
*/
|
|
108
|
+
updateUrlWithRainlang(value = this.currentRainlang) {
|
|
109
|
+
try {
|
|
110
|
+
const url = new URL(window.location.href);
|
|
111
|
+
if (value) {
|
|
112
|
+
url.searchParams.set(RainlangManager.STORAGE_KEY, value);
|
|
113
|
+
}
|
|
114
|
+
else {
|
|
115
|
+
url.searchParams.delete(RainlangManager.STORAGE_KEY);
|
|
116
|
+
}
|
|
117
|
+
window.history.pushState({}, '', url.toString());
|
|
118
|
+
}
|
|
119
|
+
catch (error) {
|
|
120
|
+
throw new Error('Failed to update URL parameter: ' +
|
|
121
|
+
(error instanceof Error ? error.message : String(error)));
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
/**
|
|
125
|
+
* Check if the current rainlang is custom (different from the default)
|
|
126
|
+
* @returns True if using a non-default rainlang
|
|
127
|
+
*/
|
|
128
|
+
isCustomRainlang() {
|
|
129
|
+
return (this.currentRainlang !== undefined &&
|
|
130
|
+
this.currentRainlang !== null &&
|
|
131
|
+
this.currentRainlang !== this.defaultRainlang);
|
|
132
|
+
}
|
|
133
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { SvelteComponent } from "svelte";
|
|
2
|
+
import type { RainlangManager } from './RainlangManager';
|
|
3
|
+
declare const __propDef: {
|
|
4
|
+
props: {
|
|
5
|
+
rainlangManager: RainlangManager;
|
|
6
|
+
};
|
|
7
|
+
events: {
|
|
8
|
+
[evt: string]: CustomEvent<any>;
|
|
9
|
+
};
|
|
10
|
+
slots: {
|
|
11
|
+
default: {};
|
|
12
|
+
};
|
|
13
|
+
exports?: {} | undefined;
|
|
14
|
+
bindings?: string | undefined;
|
|
15
|
+
};
|
|
16
|
+
export type RainlangProviderProps = typeof __propDef.props;
|
|
17
|
+
export type RainlangProviderEvents = typeof __propDef.events;
|
|
18
|
+
export type RainlangProviderSlots = typeof __propDef.slots;
|
|
19
|
+
export default class RainlangProvider extends SvelteComponent<RainlangProviderProps, RainlangProviderEvents, RainlangProviderSlots> {
|
|
20
|
+
}
|
|
21
|
+
export {};
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { RainlangManager } from './RainlangManager';
|
|
2
|
+
export declare const RAINLANG_KEY = "rainlang_key";
|
|
3
|
+
/**
|
|
4
|
+
* Retrieves the rainlang manager directly from Svelte's context
|
|
5
|
+
*/
|
|
6
|
+
export declare const getRainlangContext: () => RainlangManager;
|
|
7
|
+
/**
|
|
8
|
+
* Sets the rainlang manager in Svelte's context
|
|
9
|
+
*/
|
|
10
|
+
export declare const setRainlangContext: (rainlang: RainlangManager) => void;
|