@rainlanguage/ui-components 0.0.1-alpha.237 → 0.0.1-alpha.239
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 +14 -6
- package/dist/__fixtures__/settings.yaml +18 -20
- package/dist/__mocks__/MockCodeMirrorEditor.svelte +17 -0
- package/dist/__mocks__/MockCodeMirrorEditor.svelte.d.ts +21 -0
- package/dist/__mocks__/MockComponent.js +1 -1
- package/dist/__mocks__/MockComponent.svelte +7 -3
- package/dist/__mocks__/MockComponent.svelte.d.ts +1 -0
- package/dist/__mocks__/mockWeb3Config.d.ts +1 -1
- package/dist/__mocks__/mockWeb3Config.js +10 -7
- package/dist/__mocks__/queries.js +9 -9
- package/dist/__mocks__/stores.d.ts +4 -4
- package/dist/__mocks__/stores.js +40 -40
- package/dist/app.css +3 -3
- package/dist/components/ButtonDarkMode.svelte +7 -1
- package/dist/components/ButtonScrub.svelte +22 -0
- package/dist/components/ButtonScrub.svelte.d.ts +25 -0
- package/dist/components/ButtonVaultLink.svelte +3 -2
- package/dist/components/ButtonVaultLink.svelte.d.ts +2 -2
- package/dist/components/CodeMirrorRainlang.svelte +19 -2
- package/dist/components/CodeMirrorRainlang.svelte.d.ts +2 -1
- package/dist/components/Hash.svelte +3 -2
- package/dist/components/{ListViewOrderbookFilters.svelte → ListViewRaindexFilters.svelte} +7 -7
- package/dist/components/{ListViewOrderbookFilters.svelte.d.ts → ListViewRaindexFilters.svelte.d.ts} +7 -7
- package/dist/components/LocalDbStatusBadge.svelte.d.ts +1 -1
- package/dist/components/LocalDbStatusCard.svelte +7 -4
- package/dist/components/LocalDbStatusCard.svelte.d.ts +2 -2
- package/dist/components/LocalDbStatusModal.svelte +16 -14
- package/dist/components/LocalDbStatusModal.svelte.d.ts +2 -2
- package/dist/components/OrderOrVaultHash.svelte +2 -2
- package/dist/components/OrderOrVaultHash.svelte.d.ts +2 -2
- package/dist/components/Sensitive.svelte +16 -0
- package/dist/components/Sensitive.svelte.d.ts +28 -0
- package/dist/components/TanstackAppTable.svelte +146 -87
- package/dist/components/TanstackAppTable.svelte.d.ts +1 -1
- package/dist/components/VaultBalanceChangeTypeFilter.svelte +1 -1
- package/dist/components/VaultBalanceChangeTypeFilter.svelte.d.ts +1 -1
- package/dist/components/VaultCard.svelte +1 -1
- package/dist/components/VaultCard.svelte.d.ts +1 -1
- package/dist/components/charts/OrderTradesChart.svelte +116 -97
- package/dist/components/charts/OrderTradesChart.svelte.d.ts +2 -2
- package/dist/components/charts/transformAndSortData.d.ts +1 -1
- package/dist/components/charts/transformAndSortData.js +19 -19
- package/dist/components/deployment/DeploymentSteps.svelte +5 -2
- package/dist/components/deployment/DeploymentSteps.svelte.d.ts +1 -1
- package/dist/components/deployment/DeploymentsSection.svelte.d.ts +1 -1
- package/dist/components/deployment/DepositInput.svelte +1 -1
- package/dist/components/deployment/DepositInput.svelte.d.ts +1 -1
- package/dist/components/deployment/FieldDefinitionInput.svelte +1 -1
- package/dist/components/deployment/FieldDefinitionInput.svelte.d.ts +1 -1
- package/dist/components/deployment/OrderPage.svelte.d.ts +1 -1
- package/dist/components/deployment/SelectToken.svelte.d.ts +1 -1
- package/dist/components/deployment/TokenIOInput.svelte +1 -1
- package/dist/components/deployment/TokenIOInput.svelte.d.ts +1 -1
- package/dist/components/deployment/TokenSelectionModal.svelte.d.ts +1 -1
- package/dist/components/detail/OrderDetail.svelte +12 -6
- package/dist/components/detail/OrderDetail.svelte.d.ts +2 -2
- package/dist/components/detail/TanstackOrderQuote.svelte +22 -0
- package/dist/components/detail/TanstackOrderQuote.svelte.d.ts +1 -1
- package/dist/components/detail/VaultDetail.svelte +12 -10
- package/dist/components/detail/VaultDetail.svelte.d.ts +2 -2
- package/dist/components/dropdown/{DropdownOrderbooksFilter.svelte → DropdownRaindexesFilter.svelte} +54 -54
- package/dist/components/dropdown/DropdownRaindexesFilter.svelte.d.ts +25 -0
- package/dist/components/dropdown/DropdownTokensFilter.svelte.d.ts +1 -1
- package/dist/components/icon/Refresh.svelte +2 -1
- package/dist/components/icon/Refresh.svelte.d.ts +1 -0
- package/dist/components/input/InputTokenAmount.svelte +16 -1
- package/dist/components/input/InputTokenAmount.svelte.d.ts +1 -1
- package/dist/components/tables/OrderTradesListTable.svelte +113 -98
- package/dist/components/tables/OrderTradesListTable.svelte.d.ts +1 -1
- package/dist/components/tables/OrderVaultsVolTable.svelte +1 -1
- package/dist/components/tables/OrderVaultsVolTable.svelte.d.ts +1 -1
- package/dist/components/tables/OrdersListTable.svelte +19 -17
- package/dist/components/tables/OrdersListTable.svelte.d.ts +1 -1
- package/dist/components/tables/VaultBalanceChangesTable.svelte +1 -1
- package/dist/components/tables/VaultBalanceChangesTable.svelte.d.ts +1 -1
- package/dist/components/tables/VaultsListTable.svelte +24 -21
- package/dist/components/tables/VaultsListTable.svelte.d.ts +2 -2
- package/dist/components/transactions/FixedBottomTransaction.svelte +1 -0
- package/dist/components/transactions/getStatusEmoji.d.ts +1 -1
- package/dist/components/transactions/getStatusEmoji.js +13 -13
- package/dist/consts.js +1 -1
- package/dist/errors/DeploymentStepsError.js +3 -3
- package/dist/errors/index.d.ts +1 -1
- package/dist/errors/index.js +1 -1
- package/dist/hooks/useLocalDb.d.ts +1 -1
- package/dist/hooks/useLocalDb.js +3 -3
- package/dist/hooks/useRaindexClient.d.ts +1 -1
- package/dist/hooks/useRaindexClient.js +4 -4
- package/dist/hooks/useRaindexOrderBuilder.d.ts +1 -1
- package/dist/hooks/useRaindexOrderBuilder.js +4 -4
- package/dist/index.d.ts +122 -114
- package/dist/index.js +115 -109
- package/dist/models/Transaction.d.ts +4 -4
- package/dist/models/Transaction.js +9 -9
- package/dist/providers/RaindexClientProvider.svelte +1 -1
- package/dist/providers/RaindexClientProvider.svelte.d.ts +1 -1
- package/dist/providers/RaindexOrderBuilderProvider.svelte +1 -1
- package/dist/providers/RaindexOrderBuilderProvider.svelte.d.ts +1 -1
- package/dist/providers/dotrainRegistry/DotrainRegistryProvider.svelte.d.ts +1 -1
- package/dist/providers/dotrainRegistry/context.d.ts +2 -2
- package/dist/providers/dotrainRegistry/context.js +13 -10
- package/dist/providers/dotrainRegistry/useDotrainRegistry.d.ts +1 -1
- package/dist/providers/dotrainRegistry/useDotrainRegistry.js +8 -8
- package/dist/providers/registry/RegistryManager.js +8 -7
- package/dist/providers/registry/context.d.ts +1 -1
- package/dist/providers/registry/context.js +9 -9
- package/dist/providers/registry/useRegistry.d.ts +1 -1
- package/dist/providers/registry/useRegistry.js +5 -5
- package/dist/providers/toasts/context.d.ts +2 -2
- package/dist/providers/toasts/context.js +4 -4
- package/dist/providers/toasts/useToasts.d.ts +1 -1
- package/dist/providers/toasts/useToasts.js +4 -4
- package/dist/providers/transactions/TransactionManager.d.ts +14 -15
- package/dist/providers/transactions/TransactionManager.js +107 -107
- package/dist/providers/transactions/context.d.ts +1 -1
- package/dist/providers/transactions/context.js +4 -4
- package/dist/providers/transactions/useTransactions.js +2 -2
- package/dist/providers/wallet/context.d.ts +1 -1
- package/dist/providers/wallet/context.js +11 -11
- package/dist/providers/wallet/useAccount.js +27 -27
- package/dist/queries/keys.js +10 -10
- package/dist/queries/queryClient.d.ts +1 -1
- package/dist/queries/queryClient.js +8 -8
- package/dist/services/awaitTransactionIndexing.d.ts +8 -8
- package/dist/services/awaitTransactionIndexing.js +10 -8
- package/dist/services/getExplorerLink.js +2 -2
- package/dist/services/handleShareChoices.d.ts +1 -1
- package/dist/services/handleShareChoices.js +4 -4
- package/dist/services/historicalOrderCharts.d.ts +2 -2
- package/dist/services/historicalOrderCharts.js +260 -201
- package/dist/services/index.d.ts +5 -3
- package/dist/services/index.js +3 -2
- package/dist/services/loadRegistryUrl.d.ts +1 -1
- package/dist/services/loadRegistryUrl.js +5 -5
- package/dist/services/pairTradesChartData.d.ts +2 -2
- package/dist/services/pairTradesChartData.js +28 -24
- package/dist/services/registry.d.ts +1 -1
- package/dist/services/registry.js +10 -10
- package/dist/services/time.d.ts +1 -1
- package/dist/services/time.js +35 -35
- package/dist/services/validateAmount.d.ts +30 -0
- package/dist/services/validateAmount.js +53 -0
- package/dist/storesGeneric/cachedWritableStore.d.ts +2 -2
- package/dist/storesGeneric/cachedWritableStore.js +3 -3
- package/dist/storesGeneric/scrub.d.ts +14 -0
- package/dist/storesGeneric/scrub.js +22 -0
- package/dist/test/matchers.d.ts +2 -2
- package/dist/test/matchers.js +2 -2
- package/dist/types/account.d.ts +2 -2
- package/dist/types/appStores.d.ts +3 -3
- package/dist/types/modal.d.ts +3 -3
- package/dist/types/order.d.ts +1 -1
- package/dist/types/toast.d.ts +2 -2
- package/dist/types/tokenBalance.d.ts +1 -1
- package/dist/types/transaction.d.ts +4 -4
- package/dist/utils/breadcrumbs.js +2 -2
- package/dist/utils/codeMirrorThemes.js +80 -74
- package/dist/utils/configHelpers.d.ts +1 -1
- package/dist/utils/configHelpers.js +6 -6
- package/dist/utils/constructHashLink.d.ts +3 -3
- package/dist/utils/constructHashLink.js +39 -37
- package/dist/utils/getNetworkName.js +5 -5
- package/dist/utils/hex.js +1 -1
- package/dist/utils/lightweightChartsThemes.d.ts +1 -1
- package/dist/utils/lightweightChartsThemes.js +11 -11
- package/dist/utils/localDbStatus.d.ts +26 -0
- package/dist/utils/localDbStatus.js +22 -0
- package/dist/utils/number.js +5 -3
- package/dist/utils/stripTrailingWhitespace.d.ts +16 -0
- package/dist/utils/stripTrailingWhitespace.js +22 -0
- package/dist/utils/tokens.d.ts +1 -1
- package/dist/utils/tokens.js +1 -1
- package/dist/utils/vaultBalanceChangeLabels.d.ts +1 -1
- package/dist/utils/vaultBalanceChangeLabels.js +11 -11
- package/package.json +89 -89
- package/dist/components/dropdown/DropdownOrderbooksFilter.svelte.d.ts +0 -25
package/dist/services/index.d.ts
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
-
export { fetchParseRegistry, fetchRegistryDotrains, validateOrders } from
|
|
2
|
-
export { loadRegistryUrl } from
|
|
3
|
-
export type { RegistryDotrain, RegistryFile } from
|
|
1
|
+
export { fetchParseRegistry, fetchRegistryDotrains, validateOrders, } from "./registry";
|
|
2
|
+
export { loadRegistryUrl } from "./loadRegistryUrl";
|
|
3
|
+
export type { RegistryDotrain, RegistryFile } from "./registry";
|
|
4
|
+
export { validateAmount, countDecimalPlaces, MAX_DECIMALS, } from "./validateAmount";
|
|
5
|
+
export type { AmountDecimalsValidation } from "./validateAmount";
|
package/dist/services/index.js
CHANGED
|
@@ -1,2 +1,3 @@
|
|
|
1
|
-
export { fetchParseRegistry, fetchRegistryDotrains, validateOrders } from
|
|
2
|
-
export { loadRegistryUrl } from
|
|
1
|
+
export { fetchParseRegistry, fetchRegistryDotrains, validateOrders, } from "./registry";
|
|
2
|
+
export { loadRegistryUrl } from "./loadRegistryUrl";
|
|
3
|
+
export { validateAmount, countDecimalPlaces, MAX_DECIMALS, } from "./validateAmount";
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { RegistryManager } from
|
|
1
|
+
import { RegistryManager } from "../providers/registry/RegistryManager";
|
|
2
2
|
export declare function loadRegistryUrl(url: string, registryManager: RegistryManager): Promise<void>;
|
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
import { RegistryManager } from
|
|
2
|
-
import { DotrainRegistry } from
|
|
1
|
+
import { RegistryManager } from "../providers/registry/RegistryManager";
|
|
2
|
+
import { DotrainRegistry } from "@rainlanguage/raindex";
|
|
3
3
|
export async function loadRegistryUrl(url, registryManager) {
|
|
4
4
|
if (!url) {
|
|
5
|
-
throw new Error(
|
|
5
|
+
throw new Error("No URL provided");
|
|
6
6
|
}
|
|
7
7
|
if (!registryManager) {
|
|
8
|
-
throw new Error(
|
|
8
|
+
throw new Error("Registry manager is required");
|
|
9
9
|
}
|
|
10
10
|
try {
|
|
11
11
|
const validationResult = await DotrainRegistry.validate(url);
|
|
@@ -16,7 +16,7 @@ export async function loadRegistryUrl(url, registryManager) {
|
|
|
16
16
|
window.location.reload();
|
|
17
17
|
}
|
|
18
18
|
catch (e) {
|
|
19
|
-
const errorMessage = e instanceof Error ? e.message :
|
|
19
|
+
const errorMessage = e instanceof Error ? e.message : "Failed to update registry URL";
|
|
20
20
|
throw new Error(errorMessage);
|
|
21
21
|
}
|
|
22
22
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import type { RaindexTrade, RaindexVaultToken } from
|
|
2
|
-
import type { UTCTimestamp } from
|
|
1
|
+
import type { RaindexTrade, RaindexVaultToken } from "@rainlanguage/raindex";
|
|
2
|
+
import type { UTCTimestamp } from "lightweight-charts";
|
|
3
3
|
export declare const BUCKET_SECONDS_24_HOURS = 900;
|
|
4
4
|
export declare const BUCKET_SECONDS_7_DAYS = 3600;
|
|
5
5
|
export declare const BUCKET_SECONDS_30_DAYS = 14400;
|
|
@@ -1,16 +1,16 @@
|
|
|
1
|
-
import { sortBy } from
|
|
2
|
-
import { TIME_DELTA_24_HOURS, TIME_DELTA_7_DAYS, TIME_DELTA_30_DAYS } from
|
|
1
|
+
import { sortBy } from "lodash";
|
|
2
|
+
import { TIME_DELTA_24_HOURS, TIME_DELTA_7_DAYS, TIME_DELTA_30_DAYS, } from "./time";
|
|
3
3
|
export const BUCKET_SECONDS_24_HOURS = 900;
|
|
4
4
|
export const BUCKET_SECONDS_7_DAYS = 3600;
|
|
5
5
|
export const BUCKET_SECONDS_30_DAYS = 14400;
|
|
6
6
|
export const BUCKET_SECONDS_1_YEAR = 86400;
|
|
7
7
|
export const CHART_COLORS = {
|
|
8
|
-
BUY_VOLUME:
|
|
9
|
-
BUY_VOLUME_TRANSPARENT:
|
|
10
|
-
SELL_VOLUME:
|
|
11
|
-
SELL_VOLUME_TRANSPARENT:
|
|
12
|
-
PRICE_LINE:
|
|
13
|
-
ZERO_LINE:
|
|
8
|
+
BUY_VOLUME: "#26a69a",
|
|
9
|
+
BUY_VOLUME_TRANSPARENT: "rgba(38, 166, 154, 0.5)",
|
|
10
|
+
SELL_VOLUME: "#ef5350",
|
|
11
|
+
SELL_VOLUME_TRANSPARENT: "rgba(239, 83, 80, 0.5)",
|
|
12
|
+
PRICE_LINE: "#5c6bc0",
|
|
13
|
+
ZERO_LINE: "#888888",
|
|
14
14
|
};
|
|
15
15
|
export function getBucketSecondsForTimeDelta(timeDeltaSeconds) {
|
|
16
16
|
if (timeDeltaSeconds <= TIME_DELTA_24_HOURS)
|
|
@@ -22,19 +22,21 @@ export function getBucketSecondsForTimeDelta(timeDeltaSeconds) {
|
|
|
22
22
|
return BUCKET_SECONDS_1_YEAR;
|
|
23
23
|
}
|
|
24
24
|
function getTokenAddressLower(trade, which) {
|
|
25
|
-
const change = which ===
|
|
25
|
+
const change = which === "in"
|
|
26
|
+
? trade.inputVaultBalanceChange
|
|
27
|
+
: trade.outputVaultBalanceChange;
|
|
26
28
|
return change.token.address.toLowerCase();
|
|
27
29
|
}
|
|
28
30
|
function tradeMatchesPair(trade, baseTokenAddress, quoteTokenAddress) {
|
|
29
|
-
const inAddr = getTokenAddressLower(trade,
|
|
30
|
-
const outAddr = getTokenAddressLower(trade,
|
|
31
|
+
const inAddr = getTokenAddressLower(trade, "in");
|
|
32
|
+
const outAddr = getTokenAddressLower(trade, "out");
|
|
31
33
|
const baseLower = baseTokenAddress.toLowerCase();
|
|
32
34
|
const quoteLower = quoteTokenAddress.toLowerCase();
|
|
33
35
|
return ((inAddr === baseLower && outAddr === quoteLower) ||
|
|
34
36
|
(inAddr === quoteLower && outAddr === baseLower));
|
|
35
37
|
}
|
|
36
38
|
function getTradeAmounts(trade, baseTokenAddress) {
|
|
37
|
-
const inAddr = getTokenAddressLower(trade,
|
|
39
|
+
const inAddr = getTokenAddressLower(trade, "in");
|
|
38
40
|
const baseLower = baseTokenAddress.toLowerCase();
|
|
39
41
|
const inFormattedAmount = trade.inputVaultBalanceChange.formattedAmount;
|
|
40
42
|
const outFormattedAmount = trade.outputVaultBalanceChange.formattedAmount;
|
|
@@ -46,7 +48,7 @@ function getTradeAmounts(trade, baseTokenAddress) {
|
|
|
46
48
|
return {
|
|
47
49
|
baseAmount: isBuy ? inAmt : outAmt,
|
|
48
50
|
quoteAmount: isBuy ? outAmt : inAmt,
|
|
49
|
-
isBuy
|
|
51
|
+
isBuy,
|
|
50
52
|
};
|
|
51
53
|
}
|
|
52
54
|
export function extractPairsFromTrades(trades) {
|
|
@@ -82,7 +84,7 @@ export function getDefaultPair(trades) {
|
|
|
82
84
|
}
|
|
83
85
|
}
|
|
84
86
|
export function getTokenLabel(token) {
|
|
85
|
-
if (token.symbol && token.symbol.trim() !==
|
|
87
|
+
if (token.symbol && token.symbol.trim() !== "") {
|
|
86
88
|
return token.symbol;
|
|
87
89
|
}
|
|
88
90
|
const addr = token.address;
|
|
@@ -92,8 +94,10 @@ export function getTokenLabel(token) {
|
|
|
92
94
|
return addr;
|
|
93
95
|
}
|
|
94
96
|
export function pairsAreEqual(pairA, pairB) {
|
|
95
|
-
return (pairA.baseToken.address.toLowerCase() ===
|
|
96
|
-
|
|
97
|
+
return (pairA.baseToken.address.toLowerCase() ===
|
|
98
|
+
pairB.baseToken.address.toLowerCase() &&
|
|
99
|
+
pairA.quoteToken.address.toLowerCase() ===
|
|
100
|
+
pairB.quoteToken.address.toLowerCase());
|
|
97
101
|
}
|
|
98
102
|
export function findPairIndex(pairs, targetPair) {
|
|
99
103
|
return pairs.findIndex((p) => pairsAreEqual(p, targetPair));
|
|
@@ -101,15 +105,15 @@ export function findPairIndex(pairs, targetPair) {
|
|
|
101
105
|
export function flipTradingPair(pair) {
|
|
102
106
|
return {
|
|
103
107
|
baseToken: pair.quoteToken,
|
|
104
|
-
quoteToken: pair.baseToken
|
|
108
|
+
quoteToken: pair.baseToken,
|
|
105
109
|
};
|
|
106
110
|
}
|
|
107
111
|
export function formatChartTimestamp(timestampSeconds, timeDeltaSeconds) {
|
|
108
112
|
const date = new Date(timestampSeconds * 1000);
|
|
109
113
|
const day = date.getDate();
|
|
110
|
-
const month = date.toLocaleString(
|
|
111
|
-
const hours = date.getHours().toString().padStart(2,
|
|
112
|
-
const minutes = date.getMinutes().toString().padStart(2,
|
|
114
|
+
const month = date.toLocaleString("en-US", { month: "short" });
|
|
115
|
+
const hours = date.getHours().toString().padStart(2, "0");
|
|
116
|
+
const minutes = date.getMinutes().toString().padStart(2, "0");
|
|
113
117
|
if (timeDeltaSeconds <= TIME_DELTA_24_HOURS) {
|
|
114
118
|
return `${month} ${day} ${hours}:${minutes}`;
|
|
115
119
|
}
|
|
@@ -146,7 +150,7 @@ export function transformPairTrades(input) {
|
|
|
146
150
|
if (existing) {
|
|
147
151
|
priceAggregator.set(ts, {
|
|
148
152
|
sumBase: existing.sumBase + baseAmount,
|
|
149
|
-
sumQuote: existing.sumQuote + quoteAmount
|
|
153
|
+
sumQuote: existing.sumQuote + quoteAmount,
|
|
150
154
|
});
|
|
151
155
|
}
|
|
152
156
|
else {
|
|
@@ -171,7 +175,7 @@ export function transformPairTrades(input) {
|
|
|
171
175
|
buyVolumePoints.push({
|
|
172
176
|
time: bucketTime,
|
|
173
177
|
value: vol,
|
|
174
|
-
color: CHART_COLORS.BUY_VOLUME
|
|
178
|
+
color: CHART_COLORS.BUY_VOLUME,
|
|
175
179
|
});
|
|
176
180
|
}
|
|
177
181
|
const sellVolumePoints = [];
|
|
@@ -179,12 +183,12 @@ export function transformPairTrades(input) {
|
|
|
179
183
|
sellVolumePoints.push({
|
|
180
184
|
time: bucketTime,
|
|
181
185
|
value: -vol,
|
|
182
|
-
color: CHART_COLORS.SELL_VOLUME
|
|
186
|
+
color: CHART_COLORS.SELL_VOLUME,
|
|
183
187
|
});
|
|
184
188
|
}
|
|
185
189
|
return {
|
|
186
190
|
pricePoints: sortBy(pricePoints, (p) => p.time),
|
|
187
191
|
buyVolumePoints: sortBy(buyVolumePoints, (p) => p.time),
|
|
188
|
-
sellVolumePoints: sortBy(sellVolumePoints, (p) => p.time)
|
|
192
|
+
sellVolumePoints: sortBy(sellVolumePoints, (p) => p.time),
|
|
189
193
|
};
|
|
190
194
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { RaindexOrderBuilder } from
|
|
1
|
+
import { RaindexOrderBuilder } from "@rainlanguage/raindex";
|
|
2
2
|
/**
|
|
3
3
|
* Fetches and parses a file registry from a given URL.
|
|
4
4
|
* The registry is expected to be a text file where each line contains a file name and URL separated by a space.
|
|
@@ -15,23 +15,23 @@ export const fetchParseRegistry = async (url) => {
|
|
|
15
15
|
try {
|
|
16
16
|
const response = await fetch(url);
|
|
17
17
|
if (!response.ok) {
|
|
18
|
-
throw new Error(
|
|
18
|
+
throw new Error("Failed to fetch registry.");
|
|
19
19
|
}
|
|
20
20
|
const filesList = await response.text();
|
|
21
21
|
const files = filesList
|
|
22
|
-
.split(
|
|
22
|
+
.split("\n")
|
|
23
23
|
.filter((line) => line.trim())
|
|
24
24
|
.map((line) => {
|
|
25
|
-
const [name, url] = line.split(
|
|
25
|
+
const [name, url] = line.split(" ");
|
|
26
26
|
return { name, url };
|
|
27
27
|
});
|
|
28
28
|
if (!files) {
|
|
29
|
-
throw new Error(
|
|
29
|
+
throw new Error("Invalid stategy registry.");
|
|
30
30
|
}
|
|
31
31
|
return files;
|
|
32
32
|
}
|
|
33
33
|
catch (e) {
|
|
34
|
-
throw new Error(e instanceof Error ? e.message :
|
|
34
|
+
throw new Error(e instanceof Error ? e.message : "Unknown error.");
|
|
35
35
|
}
|
|
36
36
|
};
|
|
37
37
|
export const fetchRegistryDotrains = async (url) => {
|
|
@@ -64,8 +64,8 @@ export async function validateOrders(registryDotrains) {
|
|
|
64
64
|
valid: true,
|
|
65
65
|
data: {
|
|
66
66
|
...registryDotrain,
|
|
67
|
-
details: result.value
|
|
68
|
-
}
|
|
67
|
+
details: result.value,
|
|
68
|
+
},
|
|
69
69
|
};
|
|
70
70
|
}
|
|
71
71
|
catch (error) {
|
|
@@ -73,8 +73,8 @@ export async function validateOrders(registryDotrains) {
|
|
|
73
73
|
valid: false,
|
|
74
74
|
data: {
|
|
75
75
|
name: registryDotrain.name,
|
|
76
|
-
error: error instanceof Error ? error.message : String(error)
|
|
77
|
-
}
|
|
76
|
+
error: error instanceof Error ? error.message : String(error),
|
|
77
|
+
},
|
|
78
78
|
};
|
|
79
79
|
}
|
|
80
80
|
});
|
package/dist/services/time.d.ts
CHANGED
package/dist/services/time.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import dayjs from
|
|
2
|
-
import bigIntSupport from
|
|
3
|
-
import localizedFormat from
|
|
4
|
-
import utc from
|
|
1
|
+
import dayjs from "dayjs";
|
|
2
|
+
import bigIntSupport from "dayjs/plugin/bigIntSupport";
|
|
3
|
+
import localizedFormat from "dayjs/plugin/localizedFormat";
|
|
4
|
+
import utc from "dayjs/plugin/utc";
|
|
5
5
|
dayjs.extend(bigIntSupport);
|
|
6
6
|
dayjs.extend(localizedFormat);
|
|
7
7
|
dayjs.extend(utc);
|
|
@@ -14,12 +14,12 @@ export function dateTimestamp(date) {
|
|
|
14
14
|
return Math.floor(date.getTime() / 1000);
|
|
15
15
|
}
|
|
16
16
|
export function formatTimestampSecondsAsLocal(timestampSeconds) {
|
|
17
|
-
return dayjs(timestampSeconds * BigInt(
|
|
17
|
+
return dayjs(timestampSeconds * BigInt("1000"))
|
|
18
18
|
.utc()
|
|
19
|
-
.format(
|
|
19
|
+
.format("L LT");
|
|
20
20
|
}
|
|
21
21
|
export function timestampSecondsToUTCTimestamp(timestampSeconds) {
|
|
22
|
-
return dayjs(timestampSeconds * BigInt(
|
|
22
|
+
return dayjs(timestampSeconds * BigInt("1000")).unix();
|
|
23
23
|
}
|
|
24
24
|
/**
|
|
25
25
|
* Method to put a timeout on a promise, throws the exception if promise is not settled within the time
|
|
@@ -34,53 +34,53 @@ export async function promiseTimeout(promise, time, exception) {
|
|
|
34
34
|
let timeout;
|
|
35
35
|
return Promise.race([
|
|
36
36
|
promise,
|
|
37
|
-
new Promise((_resolve, reject) => (timeout = setTimeout(reject, time, exception)))
|
|
37
|
+
new Promise((_resolve, reject) => (timeout = setTimeout(reject, time, exception))),
|
|
38
38
|
]).finally(() => clearTimeout(timeout));
|
|
39
39
|
}
|
|
40
40
|
if (import.meta.vitest) {
|
|
41
41
|
const { describe, it, expect, vi } = import.meta.vitest;
|
|
42
|
-
describe(
|
|
43
|
-
describe(
|
|
44
|
-
it(
|
|
45
|
-
const result = formatTimestampSecondsAsLocal(BigInt(
|
|
46
|
-
expect(result).toBe(
|
|
42
|
+
describe("Date and timestamp utilities", () => {
|
|
43
|
+
describe("formatTimestampSecondsAsLocal", () => {
|
|
44
|
+
it("converts timestamp to local format", () => {
|
|
45
|
+
const result = formatTimestampSecondsAsLocal(BigInt("1672531200")); // Jan 1, 2023 12:00 AM
|
|
46
|
+
expect(result).toBe("01/01/2023 12:00 AM");
|
|
47
47
|
});
|
|
48
48
|
});
|
|
49
|
-
describe(
|
|
50
|
-
it(
|
|
51
|
-
const result = timestampSecondsToUTCTimestamp(BigInt(
|
|
49
|
+
describe("timestampSecondsToUTCTimestamp", () => {
|
|
50
|
+
it("converts bigint timestamp to UTCTimestamp", () => {
|
|
51
|
+
const result = timestampSecondsToUTCTimestamp(BigInt("1672531200"));
|
|
52
52
|
expect(result).toBe(1672531200);
|
|
53
53
|
});
|
|
54
54
|
});
|
|
55
55
|
});
|
|
56
|
-
describe(
|
|
57
|
-
it(
|
|
58
|
-
const testValue =
|
|
56
|
+
describe("promiseTimeout", () => {
|
|
57
|
+
it("resolves when promise resolves before timeout", async () => {
|
|
58
|
+
const testValue = "test";
|
|
59
59
|
const promise = Promise.resolve(testValue);
|
|
60
|
-
const result = await promiseTimeout(promise, 100, new Error(
|
|
60
|
+
const result = await promiseTimeout(promise, 100, new Error("Timeout"));
|
|
61
61
|
expect(result).toBe(testValue);
|
|
62
62
|
});
|
|
63
|
-
it(
|
|
63
|
+
it("rejects when promise times out", async () => {
|
|
64
64
|
const promise = new Promise((resolve) => setTimeout(resolve, 200));
|
|
65
|
-
const exception = new Error(
|
|
65
|
+
const exception = new Error("Timeout");
|
|
66
66
|
await expect(promiseTimeout(promise, 100, exception)).rejects.toThrow(exception);
|
|
67
67
|
});
|
|
68
|
-
it(
|
|
69
|
-
const error = new Error(
|
|
68
|
+
it("rejects when original promise rejects", async () => {
|
|
69
|
+
const error = new Error("Original rejection");
|
|
70
70
|
const promise = Promise.reject(error);
|
|
71
|
-
await expect(promiseTimeout(promise, 100, new Error(
|
|
71
|
+
await expect(promiseTimeout(promise, 100, new Error("Timeout"))).rejects.toThrow(error);
|
|
72
72
|
});
|
|
73
|
-
it(
|
|
74
|
-
vi.spyOn(global,
|
|
75
|
-
const promise = Promise.resolve(
|
|
76
|
-
await promiseTimeout(promise, 100, new Error(
|
|
73
|
+
it("clears timeout after promise resolution", async () => {
|
|
74
|
+
vi.spyOn(global, "clearTimeout");
|
|
75
|
+
const promise = Promise.resolve("test");
|
|
76
|
+
await promiseTimeout(promise, 100, new Error("Timeout"));
|
|
77
77
|
expect(clearTimeout).toHaveBeenCalled();
|
|
78
78
|
});
|
|
79
|
-
it(
|
|
80
|
-
vi.spyOn(global,
|
|
81
|
-
const promise = Promise.reject(new Error(
|
|
79
|
+
it("clears timeout after promise rejection", async () => {
|
|
80
|
+
vi.spyOn(global, "clearTimeout");
|
|
81
|
+
const promise = Promise.reject(new Error("Original rejection"));
|
|
82
82
|
try {
|
|
83
|
-
await promiseTimeout(promise, 100, new Error(
|
|
83
|
+
await promiseTimeout(promise, 100, new Error("Timeout"));
|
|
84
84
|
}
|
|
85
85
|
catch {
|
|
86
86
|
// Ignore the error
|
|
@@ -88,8 +88,8 @@ if (import.meta.vitest) {
|
|
|
88
88
|
expect(clearTimeout).toHaveBeenCalled();
|
|
89
89
|
});
|
|
90
90
|
});
|
|
91
|
-
describe(
|
|
92
|
-
it(
|
|
91
|
+
describe("dateTimestamp", () => {
|
|
92
|
+
it("should get date timestamp in seconds", () => {
|
|
93
93
|
const date = new Date(2022, 1, 16, 17, 32, 11, 168);
|
|
94
94
|
const result = dateTimestamp(date);
|
|
95
95
|
const expected = Math.floor(date.getTime() / 1000);
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The maximum number of fractional (post-decimal-point) digits that the
|
|
3
|
+
* underlying `Float` decimal parser accepts without precision loss. A value
|
|
4
|
+
* with more than this many decimal places is rejected client-side with a
|
|
5
|
+
* friendly message.
|
|
6
|
+
*/
|
|
7
|
+
export declare const MAX_DECIMALS = 67;
|
|
8
|
+
export interface AmountDecimalsValidation {
|
|
9
|
+
isValid: boolean;
|
|
10
|
+
errorMessage: string | null;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Counts the number of fractional digits in a plain decimal string.
|
|
14
|
+
*
|
|
15
|
+
* Returns `null` when the input is not a plain decimal number (empty, or
|
|
16
|
+
* containing anything other than an optional leading sign and digits around a
|
|
17
|
+
* single decimal point), so callers defer to the underlying parser for those
|
|
18
|
+
* cases.
|
|
19
|
+
*
|
|
20
|
+
* @param value The raw string entered by the user.
|
|
21
|
+
*/
|
|
22
|
+
export declare function countDecimalPlaces(value: string): number | null;
|
|
23
|
+
/**
|
|
24
|
+
* Validates that a raw amount string does not exceed the maximum supported
|
|
25
|
+
* number of decimal places.
|
|
26
|
+
*
|
|
27
|
+
* @param value The raw string entered by the user.
|
|
28
|
+
* @returns Validation result with a friendly error message when invalid.
|
|
29
|
+
*/
|
|
30
|
+
export declare function validateAmount(value: string): AmountDecimalsValidation;
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The maximum number of fractional (post-decimal-point) digits that the
|
|
3
|
+
* underlying `Float` decimal parser accepts without precision loss. A value
|
|
4
|
+
* with more than this many decimal places is rejected client-side with a
|
|
5
|
+
* friendly message.
|
|
6
|
+
*/
|
|
7
|
+
export const MAX_DECIMALS = 67;
|
|
8
|
+
/**
|
|
9
|
+
* Counts the number of fractional digits in a plain decimal string.
|
|
10
|
+
*
|
|
11
|
+
* Returns `null` when the input is not a plain decimal number (empty, or
|
|
12
|
+
* containing anything other than an optional leading sign and digits around a
|
|
13
|
+
* single decimal point), so callers defer to the underlying parser for those
|
|
14
|
+
* cases.
|
|
15
|
+
*
|
|
16
|
+
* @param value The raw string entered by the user.
|
|
17
|
+
*/
|
|
18
|
+
export function countDecimalPlaces(value) {
|
|
19
|
+
const trimmed = value.trim();
|
|
20
|
+
if (trimmed === "")
|
|
21
|
+
return null;
|
|
22
|
+
// Optional sign, integer part, optional fractional part. Plain decimal only
|
|
23
|
+
// (no scientific notation, no thousands separators) to match the inputs the
|
|
24
|
+
// `Float` decimal parser accepts.
|
|
25
|
+
const match = /^[+-]?(\d*)(?:\.(\d*))?$/.exec(trimmed);
|
|
26
|
+
if (!match)
|
|
27
|
+
return null;
|
|
28
|
+
const [, integerPart, fractionalPart] = match;
|
|
29
|
+
// Reject strings with no digits at all (e.g. ".", "+", "-").
|
|
30
|
+
if ((integerPart ?? "") === "" && (fractionalPart ?? "") === "")
|
|
31
|
+
return null;
|
|
32
|
+
return (fractionalPart ?? "").length;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Validates that a raw amount string does not exceed the maximum supported
|
|
36
|
+
* number of decimal places.
|
|
37
|
+
*
|
|
38
|
+
* @param value The raw string entered by the user.
|
|
39
|
+
* @returns Validation result with a friendly error message when invalid.
|
|
40
|
+
*/
|
|
41
|
+
export function validateAmount(value) {
|
|
42
|
+
const decimals = countDecimalPlaces(value);
|
|
43
|
+
if (decimals !== null && decimals > MAX_DECIMALS) {
|
|
44
|
+
return {
|
|
45
|
+
isValid: false,
|
|
46
|
+
errorMessage: `Too many decimal places. A maximum of ${MAX_DECIMALS} decimal places is allowed.`,
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
return {
|
|
50
|
+
isValid: true,
|
|
51
|
+
errorMessage: null,
|
|
52
|
+
};
|
|
53
|
+
}
|
|
@@ -46,7 +46,7 @@ export declare const cachedWritableOptionalStore: <T>(key: string, defaultValue:
|
|
|
46
46
|
* @param {number | undefined} defaultValue - The default value if nothing is found in localStorage
|
|
47
47
|
* @returns A writable store that persists to localStorage and can hold an optional number
|
|
48
48
|
*/
|
|
49
|
-
export declare const cachedWritableIntOptional: (key: string, defaultValue?: undefined) => import("svelte/store").Writable<number | undefined>;
|
|
49
|
+
export declare const cachedWritableIntOptional: (key: string, defaultValue?: number | undefined) => import("svelte/store").Writable<number | undefined>;
|
|
50
50
|
/**
|
|
51
51
|
* Creates a writable store that can hold an optional string value and persists to localStorage.
|
|
52
52
|
*
|
|
@@ -54,4 +54,4 @@ export declare const cachedWritableIntOptional: (key: string, defaultValue?: und
|
|
|
54
54
|
* @param {string | undefined} defaultValue - The default value if nothing is found in localStorage
|
|
55
55
|
* @returns A writable store that persists to localStorage and can hold an optional string
|
|
56
56
|
*/
|
|
57
|
-
export declare const cachedWritableStringOptional: (key: string, defaultValue?: undefined) => import("svelte/store").Writable<string | undefined>;
|
|
57
|
+
export declare const cachedWritableStringOptional: (key: string, defaultValue?: string | undefined) => import("svelte/store").Writable<string | undefined>;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { writable } from
|
|
1
|
+
import { writable } from "svelte/store";
|
|
2
2
|
/**
|
|
3
3
|
* Creates a writable Svelte store that persists its value to localStorage.
|
|
4
4
|
*
|
|
@@ -56,7 +56,7 @@ export function cachedWritableStore(key, defaultValue, serialize, deserialize) {
|
|
|
56
56
|
});
|
|
57
57
|
return data;
|
|
58
58
|
}
|
|
59
|
-
export const cachedWritableString = (key, defaultValue =
|
|
59
|
+
export const cachedWritableString = (key, defaultValue = "") => cachedWritableStore(key, defaultValue, (v) => v, (v) => v);
|
|
60
60
|
export const cachedWritableInt = (key, defaultValue = 0) => cachedWritableStore(key, defaultValue, (v) => v.toString(), (v) => {
|
|
61
61
|
const parsed = Number.parseInt(v);
|
|
62
62
|
return isNaN(parsed) ? defaultValue : parsed;
|
|
@@ -71,7 +71,7 @@ export const cachedWritableInt = (key, defaultValue = 0) => cachedWritableStore(
|
|
|
71
71
|
* @param {function} deserialize - Function to convert the stored string back to a value
|
|
72
72
|
* @returns A writable store that persists to localStorage and can hold undefined values
|
|
73
73
|
*/
|
|
74
|
-
export const cachedWritableOptionalStore = (key, defaultValue = undefined, serialize, deserialize) => cachedWritableStore(key, defaultValue, (v) => (v !== undefined ? serialize(v) :
|
|
74
|
+
export const cachedWritableOptionalStore = (key, defaultValue = undefined, serialize, deserialize) => cachedWritableStore(key, defaultValue, (v) => (v !== undefined ? serialize(v) : ""), (v) => (v !== "" ? deserialize(v) : undefined));
|
|
75
75
|
/**
|
|
76
76
|
* Creates a writable store that can hold an optional number value and persists to localStorage.
|
|
77
77
|
*
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Global "scrub" toggle used for safe screenshotting of the GUI.
|
|
3
|
+
*
|
|
4
|
+
* When `true`, every {@link Sensitive} region (which wraps all rendered
|
|
5
|
+
* addresses and transaction hashes via the `Hash` component) is masked with an
|
|
6
|
+
* opaque grey box so that sharing a screenshot does not leak addresses/hashes.
|
|
7
|
+
*
|
|
8
|
+
* This is purely presentational: it never changes any on-chain data or the
|
|
9
|
+
* underlying values held in memory, only how they are displayed.
|
|
10
|
+
*
|
|
11
|
+
* The value is persisted to localStorage under the `scrub` key so the masked
|
|
12
|
+
* state survives reloads while a user is preparing screenshots.
|
|
13
|
+
*/
|
|
14
|
+
export declare const scrub: import("svelte/store").Writable<boolean>;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { cachedWritableStore } from "./cachedWritableStore";
|
|
2
|
+
/**
|
|
3
|
+
* Global "scrub" toggle used for safe screenshotting of the GUI.
|
|
4
|
+
*
|
|
5
|
+
* When `true`, every {@link Sensitive} region (which wraps all rendered
|
|
6
|
+
* addresses and transaction hashes via the `Hash` component) is masked with an
|
|
7
|
+
* opaque grey box so that sharing a screenshot does not leak addresses/hashes.
|
|
8
|
+
*
|
|
9
|
+
* This is purely presentational: it never changes any on-chain data or the
|
|
10
|
+
* underlying values held in memory, only how they are displayed.
|
|
11
|
+
*
|
|
12
|
+
* The value is persisted to localStorage under the `scrub` key so the masked
|
|
13
|
+
* state survives reloads while a user is preparing screenshots.
|
|
14
|
+
*/
|
|
15
|
+
export const scrub = cachedWritableStore("scrub", false, (value) => JSON.stringify(value), (serialized) => {
|
|
16
|
+
try {
|
|
17
|
+
return JSON.parse(serialized) === true;
|
|
18
|
+
}
|
|
19
|
+
catch {
|
|
20
|
+
return false;
|
|
21
|
+
}
|
|
22
|
+
});
|
package/dist/test/matchers.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import * as matchers from
|
|
1
|
+
import * as matchers from "@testing-library/jest-dom/matchers";
|
|
2
2
|
export declare const expect: import("vitest").ExpectStatic;
|
|
3
|
-
declare module
|
|
3
|
+
declare module "vitest" {
|
|
4
4
|
interface JestAssertion<T = any> extends matchers.TestingLibraryMatchers<ReturnType<typeof expect.stringContaining>, T> {
|
|
5
5
|
}
|
|
6
6
|
}
|
package/dist/test/matchers.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { expect as vitestExpect } from
|
|
2
|
-
import * as matchers from
|
|
1
|
+
import { expect as vitestExpect } from "vitest";
|
|
2
|
+
import * as matchers from "@testing-library/jest-dom/matchers";
|
|
3
3
|
vitestExpect.extend(matchers);
|
|
4
4
|
export const expect = vitestExpect;
|
package/dist/types/account.d.ts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import type { Readable } from
|
|
2
|
-
import type { Hex } from
|
|
1
|
+
import type { Readable } from "svelte/store";
|
|
2
|
+
import type { Hex } from "viem";
|
|
3
3
|
export type Account = Readable<Hex | null>;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import type { Writable } from
|
|
2
|
-
import type { Address, Hex } from
|
|
1
|
+
import type { Writable } from "svelte/store";
|
|
2
|
+
import type { Address, Hex } from "@rainlanguage/raindex";
|
|
3
3
|
export interface AppStoresInterface {
|
|
4
4
|
selectedChainIds: Writable<number[]>;
|
|
5
5
|
showInactiveOrders: Writable<boolean>;
|
|
@@ -7,6 +7,6 @@ export interface AppStoresInterface {
|
|
|
7
7
|
hideZeroBalanceVaults: Writable<boolean>;
|
|
8
8
|
hideInactiveOrdersVaults: Writable<boolean>;
|
|
9
9
|
activeTokens: Writable<Address[]>;
|
|
10
|
-
|
|
10
|
+
activeRaindexAddresses: Writable<Address[]>;
|
|
11
11
|
ownerFilter: Writable<Address>;
|
|
12
12
|
}
|
package/dist/types/modal.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import type { Float, RaindexOrder, RaindexVault } from
|
|
2
|
-
import type { VaultActionArgs } from
|
|
3
|
-
import type { Hex } from
|
|
1
|
+
import type { Float, RaindexOrder, RaindexVault } from "@rainlanguage/raindex";
|
|
2
|
+
import type { VaultActionArgs } from "./transaction";
|
|
3
|
+
import type { Hex } from "viem";
|
|
4
4
|
export type VaultActionModalProps = {
|
|
5
5
|
open: boolean;
|
|
6
6
|
args: VaultActionArgs;
|
package/dist/types/order.d.ts
CHANGED
package/dist/types/toast.d.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
export interface ToastProps {
|
|
2
2
|
message: string;
|
|
3
3
|
detail?: string;
|
|
4
|
-
type:
|
|
5
|
-
color:
|
|
4
|
+
type: "success" | "error" | "warning" | "info";
|
|
5
|
+
color: "green" | "red" | "yellow" | "blue";
|
|
6
6
|
links?: ToastLink[];
|
|
7
7
|
}
|
|
8
8
|
export type ToastLink = {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import type { Hex } from
|
|
2
|
-
import type { RaindexVault } from
|
|
3
|
-
import type { ToastLink } from
|
|
4
|
-
import type { TransactionStoreState } from
|
|
1
|
+
import type { Hex } from "viem";
|
|
2
|
+
import type { RaindexVault } from "@rainlanguage/raindex";
|
|
3
|
+
import type { ToastLink } from "./toast";
|
|
4
|
+
import type { TransactionStoreState } from "../models/Transaction";
|
|
5
5
|
/**
|
|
6
6
|
* Context provided to the indexing function, allowing it to update
|
|
7
7
|
* transaction state and trigger callbacks without TransactionStore
|