atom.io 0.1.0 → 0.3.0

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.
@@ -0,0 +1,196 @@
1
+ import HAMT from "hamt_plus"
2
+
3
+ import type { KeyedStateUpdate, TransactionUpdate, Store } from "."
4
+ import { IMPLICIT, withdraw } from "."
5
+ import { setState } from ".."
6
+ import type { AtomToken, TimelineOptions, TimelineToken, ƒn } from ".."
7
+
8
+ export type Timeline = {
9
+ key: string
10
+ type: `timeline`
11
+ next: () => void
12
+ prev: () => void
13
+ }
14
+
15
+ export type TimelineStateUpdate = KeyedStateUpdate<unknown> & {
16
+ type: `state_update`
17
+ }
18
+ export type TimelineTransactionUpdate = TransactionUpdate<ƒn> & {
19
+ type: `transaction_update`
20
+ }
21
+
22
+ export type TimelineData = {
23
+ at: number
24
+ timeTraveling: boolean
25
+ history: (TimelineStateUpdate | TimelineTransactionUpdate)[]
26
+ }
27
+
28
+ export function timeline__INTERNAL(
29
+ options: TimelineOptions,
30
+ store: Store = IMPLICIT.STORE
31
+ ): TimelineToken {
32
+ let incompleteTransactionKey: string | null = null
33
+ const timelineData: TimelineData = {
34
+ at: 0,
35
+ timeTraveling: false,
36
+ history: [],
37
+ }
38
+
39
+ const subscribeToAtom = (token: AtomToken<any>) => {
40
+ const state = withdraw(token, store)
41
+ state.subject.subscribe((update) => {
42
+ const storeCurrentTransactionKey =
43
+ store.transactionStatus.phase === `applying`
44
+ ? store.transactionStatus.key
45
+ : null
46
+ store.config.logger?.info(
47
+ `⏳ timeline "${options.key}" saw atom "${token.key}" go (`,
48
+ update.oldValue,
49
+ `->`,
50
+ update.newValue,
51
+ storeCurrentTransactionKey
52
+ ? `) in "${storeCurrentTransactionKey}"`
53
+ : `) independently`
54
+ )
55
+
56
+ if (
57
+ storeCurrentTransactionKey &&
58
+ store.transactionStatus.phase === `applying`
59
+ ) {
60
+ const currentTransaction = withdraw(
61
+ { key: storeCurrentTransactionKey, type: `transaction` },
62
+ store
63
+ )
64
+ if (incompleteTransactionKey !== storeCurrentTransactionKey) {
65
+ if (incompleteTransactionKey) {
66
+ store.config.logger?.error(
67
+ `Timeline "${options.key}" was unable to resolve transaction "${incompleteTransactionKey}. This is probably a bug.`
68
+ )
69
+ }
70
+ incompleteTransactionKey = storeCurrentTransactionKey
71
+ const subscription = currentTransaction.subject.subscribe((update) => {
72
+ if (timelineData.timeTraveling === false) {
73
+ timelineData.history.push({
74
+ type: `transaction_update`,
75
+ ...update,
76
+ atomUpdates: update.atomUpdates.filter((atomUpdate) =>
77
+ options.atoms.some((atom) => atom.key === atomUpdate.key)
78
+ ),
79
+ })
80
+ }
81
+ timelineData.at = timelineData.history.length
82
+ subscription.unsubscribe()
83
+ incompleteTransactionKey = null
84
+ store.config.logger?.info(
85
+ `⌛ timeline "${options.key}" pushed a transaction_update from "${update.key}"`
86
+ )
87
+ })
88
+ }
89
+ } else {
90
+ if (timelineData.timeTraveling === false) {
91
+ timelineData.history.push({
92
+ type: `state_update`,
93
+ key: token.key,
94
+ oldValue: update.oldValue,
95
+ newValue: update.newValue,
96
+ })
97
+ store.config.logger?.info(
98
+ `⌛ timeline "${options.key}" pushed a state_update to "${token.key}"`
99
+ )
100
+ timelineData.at = timelineData.history.length
101
+ }
102
+ }
103
+ })
104
+ }
105
+
106
+ for (const tokenOrFamily of options.atoms) {
107
+ if (tokenOrFamily.type === `atom_family`) {
108
+ const family = tokenOrFamily
109
+ family.subject.subscribe((token) => subscribeToAtom(token))
110
+ } else {
111
+ const token = tokenOrFamily
112
+ subscribeToAtom(token)
113
+ }
114
+ }
115
+
116
+ store.timelineStore = HAMT.set(options.key, timelineData, store.timelineStore)
117
+
118
+ return {
119
+ key: options.key,
120
+ type: `timeline`,
121
+ }
122
+ }
123
+
124
+ export const redo__INTERNAL = (
125
+ token: TimelineToken,
126
+ store: Store = IMPLICIT.STORE
127
+ ): void => {
128
+ const timelineData = store.timelineStore.get(token.key)
129
+ if (!timelineData) {
130
+ store.config.logger?.error(
131
+ `Tried to redo on timeline "${token.key}" has not been initialized.`
132
+ )
133
+ return
134
+ }
135
+ if (timelineData.at === timelineData.history.length) {
136
+ store.config.logger?.warn(
137
+ `Tried to redo on timeline "${token.key}" but there is nothing to redo.`
138
+ )
139
+ return
140
+ }
141
+ timelineData.timeTraveling = true
142
+ const update = timelineData.history[timelineData.at]
143
+ switch (update.type) {
144
+ case `state_update`: {
145
+ const { key, newValue } = update
146
+ setState({ key, type: `atom` }, newValue)
147
+ break
148
+ }
149
+ case `transaction_update`: {
150
+ for (const atomUpdate of update.atomUpdates) {
151
+ const { key, newValue } = atomUpdate
152
+ setState({ key, type: `atom` }, newValue)
153
+ }
154
+ break
155
+ }
156
+ }
157
+ ++timelineData.at
158
+ timelineData.timeTraveling = false
159
+ }
160
+
161
+ export const undo__INTERNAL = (
162
+ token: TimelineToken,
163
+ store: Store = IMPLICIT.STORE
164
+ ): void => {
165
+ const timelineData = store.timelineStore.get(token.key)
166
+ if (!timelineData) {
167
+ store.config.logger?.error(
168
+ `Tried to undo on timeline "${token.key}" has not been initialized.`
169
+ )
170
+ return
171
+ }
172
+ if (timelineData.at === 0) {
173
+ store.config.logger?.warn(
174
+ `Tried to undo on timeline "${token.key}" but there is nothing to undo.`
175
+ )
176
+ return
177
+ }
178
+ timelineData.timeTraveling = true
179
+ --timelineData.at
180
+ const update = timelineData.history[timelineData.at]
181
+ switch (update.type) {
182
+ case `state_update`: {
183
+ const { key, oldValue } = update
184
+ setState({ key, type: `atom` }, oldValue)
185
+ break
186
+ }
187
+ case `transaction_update`: {
188
+ for (const atomUpdate of update.atomUpdates) {
189
+ const { key, oldValue } = atomUpdate
190
+ setState({ key, type: `atom` }, oldValue)
191
+ }
192
+ break
193
+ }
194
+ }
195
+ timelineData.timeTraveling = false
196
+ }
@@ -0,0 +1,175 @@
1
+ import HAMT from "hamt_plus"
2
+ import * as Rx from "rxjs"
3
+
4
+ import type { Store, StoreCore } from "."
5
+ import { deposit, withdraw, IMPLICIT } from "."
6
+ import { getState, setState } from ".."
7
+ import type {
8
+ AtomToken,
9
+ StateUpdate,
10
+ Transaction,
11
+ TransactionOptions,
12
+ TransactionToken,
13
+ ƒn,
14
+ } from ".."
15
+
16
+ export const TRANSACTION_PHASES = [`idle`, `building`, `applying`] as const
17
+ export type TransactionPhase = (typeof TRANSACTION_PHASES)[number]
18
+
19
+ export type KeyedStateUpdate<T> = StateUpdate<T> & {
20
+ key: string
21
+ }
22
+ export type TransactionUpdate<ƒ extends ƒn> = {
23
+ key: string
24
+ atomUpdates: KeyedStateUpdate<unknown>[]
25
+ params: Parameters<ƒ>
26
+ output: ReturnType<ƒ>
27
+ }
28
+
29
+ export type TransactionUpdateInProgress<ƒ extends ƒn> = TransactionUpdate<ƒ> & {
30
+ phase: `applying` | `building`
31
+ core: StoreCore
32
+ }
33
+ export type TransactionIdle = {
34
+ phase: `idle`
35
+ }
36
+ export type TransactionStatus<ƒ extends ƒn> =
37
+ | TransactionIdle
38
+ | TransactionUpdateInProgress<ƒ>
39
+
40
+ export const buildTransaction = (
41
+ key: string,
42
+ params: any[],
43
+ store: Store
44
+ ): void => {
45
+ store.transactionStatus = {
46
+ key,
47
+ phase: `building`,
48
+ core: {
49
+ atoms: store.atoms,
50
+ atomsThatAreDefault: store.atomsThatAreDefault,
51
+ operation: { open: false },
52
+ readonlySelectors: store.readonlySelectors,
53
+ timelines: store.timelines,
54
+ timelineAtoms: store.timelineAtoms,
55
+ transactions: store.transactions,
56
+ selectorAtoms: store.selectorAtoms,
57
+ selectorGraph: store.selectorGraph,
58
+ selectors: store.selectors,
59
+ valueMap: store.valueMap,
60
+ },
61
+ atomUpdates: [],
62
+ params,
63
+ output: undefined,
64
+ }
65
+ store.config.logger?.info(`🛫`, `transaction "${key}" started`)
66
+ }
67
+ export const applyTransaction = <ƒ extends ƒn>(
68
+ output: ReturnType<ƒ>,
69
+ store: Store
70
+ ): void => {
71
+ if (store.transactionStatus.phase !== `building`) {
72
+ store.config.logger?.warn(
73
+ `abortTransaction called outside of a transaction. This is probably a bug.`
74
+ )
75
+ return
76
+ }
77
+ store.config.logger?.info(
78
+ ` ▶️ apply transaction "${store.transactionStatus.key}" (init)`
79
+ )
80
+ store.transactionStatus.phase = `applying`
81
+ store.transactionStatus.output = output
82
+ const { atomUpdates } = store.transactionStatus
83
+ for (const { key, oldValue, newValue } of atomUpdates) {
84
+ const token: AtomToken<unknown> = { key, type: `atom` }
85
+ const state = withdraw(token, store)
86
+ setState(state, newValue, store)
87
+ }
88
+ const myTransaction = withdraw<ƒ>(
89
+ { key: store.transactionStatus.key, type: `transaction` },
90
+ store
91
+ )
92
+ myTransaction.subject.next({
93
+ key: store.transactionStatus.key,
94
+ atomUpdates,
95
+ output,
96
+ params: store.transactionStatus.params as Parameters<ƒ>,
97
+ })
98
+ store.transactionStatus = { phase: `idle` }
99
+ store.config.logger?.info(`🛬`, `transaction done`)
100
+ }
101
+ export const undoTransactionUpdate = <ƒ extends ƒn>(
102
+ update: TransactionUpdate<ƒ>,
103
+ store: Store
104
+ ): void => {
105
+ store.config.logger?.info(` ⏮ undo transaction "${update.key}" (undo)`)
106
+ for (const { key, oldValue, newValue } of update.atomUpdates) {
107
+ const token: AtomToken<unknown> = { key, type: `atom` }
108
+ const state = withdraw(token, store)
109
+ setState(state, oldValue, store)
110
+ }
111
+ }
112
+ export const redoTransactionUpdate = <ƒ extends ƒn>(
113
+ update: TransactionUpdate<ƒ>,
114
+ store: Store
115
+ ): void => {
116
+ store.config.logger?.info(` ⏭ redo transaction "${update.key}" (redo)`)
117
+ for (const { key, oldValue, newValue } of update.atomUpdates) {
118
+ const token: AtomToken<unknown> = { key, type: `atom` }
119
+ const state = withdraw(token, store)
120
+ setState(state, newValue, store)
121
+ }
122
+ }
123
+
124
+ export const abortTransaction = (store: Store): void => {
125
+ if (store.transactionStatus.phase === `idle`) {
126
+ store.config.logger?.warn(
127
+ `abortTransaction called outside of a transaction. This is probably a bug.`
128
+ )
129
+ return
130
+ }
131
+ store.transactionStatus = { phase: `idle` }
132
+ store.config.logger?.info(`🪂`, `transaction fail`)
133
+ }
134
+
135
+ export function transaction__INTERNAL<ƒ extends ƒn>(
136
+ options: TransactionOptions<ƒ>,
137
+ store: Store = IMPLICIT.STORE
138
+ ): TransactionToken<ƒ> {
139
+ const newTransaction: Transaction<ƒ> = {
140
+ key: options.key,
141
+ type: `transaction`,
142
+ run: (...params: Parameters<ƒ>) => {
143
+ buildTransaction(options.key, params, store)
144
+ try {
145
+ const output = options.do(
146
+ {
147
+ get: (token) => getState(token, store),
148
+ set: (token, value) => setState(token, value, store),
149
+ },
150
+ ...params
151
+ )
152
+ applyTransaction(output, store)
153
+ return output
154
+ } catch (thrown) {
155
+ abortTransaction(store)
156
+ store.config.logger?.error(`Transaction ${options.key} failed`, thrown)
157
+ throw thrown
158
+ }
159
+ },
160
+ subject: new Rx.Subject(),
161
+ }
162
+ const core = target(store)
163
+ core.transactions = HAMT.set(
164
+ newTransaction.key,
165
+ newTransaction,
166
+ core.transactions
167
+ )
168
+ const token = deposit(newTransaction)
169
+ return token
170
+ }
171
+
172
+ export const target = (store: Store = IMPLICIT.STORE): StoreCore =>
173
+ store.transactionStatus.phase === `building`
174
+ ? store.transactionStatus.core
175
+ : store
@@ -0,0 +1,64 @@
1
+ import type Preact from "preact/hooks"
2
+
3
+ import type React from "react"
4
+
5
+ import { subscribe, setState, __INTERNAL__ } from "atom.io"
6
+ import type { ReadonlyValueToken, StateToken } from "atom.io"
7
+
8
+ import type { Modifier } from "~/packages/anvl/src/function"
9
+
10
+ export type AtomStoreReactConfig = {
11
+ useState: typeof Preact.useState | typeof React.useState
12
+ useEffect: typeof Preact.useEffect | typeof React.useEffect
13
+ store?: __INTERNAL__.Store
14
+ }
15
+
16
+ /* eslint-disable @typescript-eslint/explicit-module-boundary-types */
17
+ export const composeStoreHooks = ({
18
+ useState,
19
+ useEffect,
20
+ store = __INTERNAL__.IMPLICIT.STORE,
21
+ }: AtomStoreReactConfig) => {
22
+ function useI<T>(token: StateToken<T>): (next: Modifier<T> | T) => void {
23
+ const updateState = (next: Modifier<T> | T) => setState(token, next, store)
24
+ return updateState
25
+ }
26
+
27
+ function useO<T>(token: ReadonlyValueToken<T> | StateToken<T>): T {
28
+ const state = __INTERNAL__.withdraw(token, store)
29
+ const initialValue = __INTERNAL__.getState__INTERNAL(state, store)
30
+ const [current, dispatch] = useState(initialValue)
31
+ useEffect(() => {
32
+ const unsubscribe = subscribe(
33
+ token,
34
+ ({ newValue, oldValue }) => {
35
+ if (oldValue !== newValue) {
36
+ dispatch(newValue)
37
+ }
38
+ },
39
+ store
40
+ )
41
+ return unsubscribe
42
+ }, [])
43
+
44
+ return current
45
+ }
46
+
47
+ function useIO<T>(token: StateToken<T>): [T, (next: Modifier<T> | T) => void] {
48
+ return [useO(token), useI(token)]
49
+ }
50
+
51
+ function useStore<T>(
52
+ token: StateToken<T>
53
+ ): [T, (next: Modifier<T> | T) => void]
54
+ function useStore<T>(token: ReadonlyValueToken<T>): T
55
+ function useStore<T>(
56
+ token: ReadonlyValueToken<T> | StateToken<T>
57
+ ): T | [T, (next: Modifier<T> | T) => void] {
58
+ if (token.type === `readonly_selector`) {
59
+ return useO(token)
60
+ }
61
+ return useIO(token)
62
+ }
63
+ return { useI, useO, useIO, useStore }
64
+ }
@@ -0,0 +1,62 @@
1
+ import type * as Rx from "rxjs"
2
+
3
+ import type { Serializable } from "~/packages/anvl/src/json"
4
+
5
+ import type { ReadonlyValueToken, SelectorToken } from "."
6
+ import { selectorFamily__INTERNAL, selector__INTERNAL } from "./internal"
7
+ import type { ReadonlyTransactors, Transactors } from "./transaction"
8
+
9
+ export type SelectorOptions<T> = {
10
+ key: string
11
+ get: (readonlyTransactors: ReadonlyTransactors) => T
12
+ set: (transactors: Transactors, newValue: T) => void
13
+ }
14
+ export type ReadonlySelectorOptions<T> = Omit<SelectorOptions<T>, `set`>
15
+
16
+ export function selector<T>(options: SelectorOptions<T>): SelectorToken<T>
17
+ export function selector<T>(
18
+ options: ReadonlySelectorOptions<T>
19
+ ): ReadonlyValueToken<T>
20
+ export function selector<T>(
21
+ options: ReadonlySelectorOptions<T> | SelectorOptions<T>
22
+ ): ReadonlyValueToken<T> | SelectorToken<T> {
23
+ return selector__INTERNAL(options)
24
+ }
25
+
26
+ export type SelectorFamilyOptions<T, K extends Serializable> = {
27
+ key: string
28
+ get: (key: K) => (readonlyTransactors: ReadonlyTransactors) => T
29
+ set: (key: K) => (transactors: Transactors, newValue: T) => void
30
+ }
31
+ export type ReadonlySelectorFamilyOptions<T, K extends Serializable> = Omit<
32
+ SelectorFamilyOptions<T, K>,
33
+ `set`
34
+ >
35
+
36
+ export type SelectorFamily<T, K extends Serializable = Serializable> = ((
37
+ key: K
38
+ ) => SelectorToken<T>) & {
39
+ key: string
40
+ type: `selector_family`
41
+ subject: Rx.Subject<SelectorToken<T>>
42
+ }
43
+
44
+ export type ReadonlySelectorFamily<T, K extends Serializable = Serializable> = ((
45
+ key: K
46
+ ) => ReadonlyValueToken<T>) & {
47
+ key: string
48
+ type: `readonly_selector_family`
49
+ subject: Rx.Subject<ReadonlyValueToken<T>>
50
+ }
51
+
52
+ export function selectorFamily<T, K extends Serializable>(
53
+ options: SelectorFamilyOptions<T, K>
54
+ ): SelectorFamily<T, K>
55
+ export function selectorFamily<T, K extends Serializable>(
56
+ options: ReadonlySelectorFamilyOptions<T, K>
57
+ ): ReadonlySelectorFamily<T, K>
58
+ export function selectorFamily<T, K extends Serializable>(
59
+ options: ReadonlySelectorFamilyOptions<T, K> | SelectorFamilyOptions<T, K>
60
+ ): ReadonlySelectorFamily<T, K> | SelectorFamily<T, K> {
61
+ return selectorFamily__INTERNAL(options)
62
+ }
@@ -0,0 +1,55 @@
1
+ import type { ReadonlyValueToken, StateToken, TransactionToken, ƒn } from "."
2
+ import type { Store, TransactionUpdate } from "./internal"
3
+ import { IMPLICIT, subscribeToRootAtoms, withdraw } from "./internal"
4
+
5
+ export type StateUpdate<T> = { newValue: T; oldValue: T }
6
+ export type UpdateHandler<T> = (update: StateUpdate<T>) => void
7
+
8
+ export const subscribe = <T>(
9
+ token: ReadonlyValueToken<T> | StateToken<T>,
10
+ handleUpdate: UpdateHandler<T>,
11
+ store: Store = IMPLICIT.STORE
12
+ ): (() => void) => {
13
+ const state = withdraw<T>(token, store)
14
+ const subscription = state.subject.subscribe(handleUpdate)
15
+ store.config.logger?.info(`👀 subscribe to "${state.key}"`)
16
+ const dependencySubscriptions =
17
+ `get` in state ? subscribeToRootAtoms(state, store) : null
18
+
19
+ const unsubscribe =
20
+ dependencySubscriptions === null
21
+ ? () => {
22
+ store.config.logger?.info(`🙈 unsubscribe from "${state.key}"`)
23
+ subscription.unsubscribe()
24
+ }
25
+ : () => {
26
+ store.config.logger?.info(
27
+ `🙈 unsubscribe from "${state.key}" and its dependencies`
28
+ )
29
+ subscription.unsubscribe()
30
+ for (const dependencySubscription of dependencySubscriptions) {
31
+ dependencySubscription.unsubscribe()
32
+ }
33
+ }
34
+
35
+ return unsubscribe
36
+ }
37
+
38
+ export type TransactionUpdateHandler<ƒ extends ƒn> = (
39
+ data: TransactionUpdate<ƒ>
40
+ ) => void
41
+
42
+ export const subscribeToTransaction = <ƒ extends ƒn>(
43
+ token: TransactionToken<ƒ>,
44
+ handleUpdate: TransactionUpdateHandler<ƒ>,
45
+ store = IMPLICIT.STORE
46
+ ): (() => void) => {
47
+ const tx = withdraw(token, store)
48
+ store.config.logger?.info(`👀 subscribe to transaction "${token.key}"`)
49
+ const subscription = tx.subject.subscribe(handleUpdate)
50
+ const unsubscribe = () => {
51
+ store.config.logger?.info(`🙈 unsubscribe from transaction "${token.key}"`)
52
+ subscription.unsubscribe()
53
+ }
54
+ return unsubscribe
55
+ }
@@ -0,0 +1,34 @@
1
+ import HAMT from "hamt_plus"
2
+ import type * as Rx from "rxjs"
3
+
4
+ import type { AtomFamily, AtomToken, ƒn } from "."
5
+ import { setState } from "."
6
+ import type { Store, KeyedStateUpdate, TransactionUpdate } from "./internal"
7
+ import { target, IMPLICIT, withdraw } from "./internal"
8
+ import {
9
+ redo__INTERNAL,
10
+ timeline__INTERNAL,
11
+ undo__INTERNAL,
12
+ } from "./internal/timeline-internal"
13
+
14
+ export type TimelineToken = {
15
+ key: string
16
+ type: `timeline`
17
+ }
18
+
19
+ export type TimelineOptions = {
20
+ key: string
21
+ atoms: (AtomFamily<any> | AtomToken<any>)[]
22
+ }
23
+
24
+ export const timeline = (options: TimelineOptions): TimelineToken => {
25
+ return timeline__INTERNAL(options)
26
+ }
27
+
28
+ export const redo = (token: TimelineToken): void => {
29
+ return redo__INTERNAL(token, IMPLICIT.STORE)
30
+ }
31
+
32
+ export const undo = (token: TimelineToken): void => {
33
+ return undo__INTERNAL(token, IMPLICIT.STORE)
34
+ }
@@ -0,0 +1,41 @@
1
+ import type * as Rx from "rxjs"
2
+
3
+ import type { ReadonlyValueToken, StateToken, TransactionToken } from "."
4
+ import type { Store, TransactionUpdate } from "./internal"
5
+ import { IMPLICIT, transaction__INTERNAL, withdraw } from "./internal"
6
+
7
+ export type ƒn = (...parameters: any[]) => any
8
+
9
+ export type Transactors = {
10
+ get: <S>(state: ReadonlyValueToken<S> | StateToken<S>) => S
11
+ set: <S>(state: StateToken<S>, newValue: S | ((oldValue: S) => S)) => void
12
+ }
13
+ export type ReadonlyTransactors = Pick<Transactors, `get`>
14
+
15
+ export type Action<ƒ extends ƒn> = (
16
+ transactors: Transactors,
17
+ ...parameters: Parameters<ƒ>
18
+ ) => ReturnType<ƒ>
19
+
20
+ export type TransactionOptions<ƒ extends ƒn> = {
21
+ key: string
22
+ do: Action<ƒ>
23
+ }
24
+
25
+ export type Transaction<ƒ extends ƒn> = {
26
+ key: string
27
+ type: `transaction`
28
+ run: (...parameters: Parameters<ƒ>) => ReturnType<ƒ>
29
+ subject: Rx.Subject<TransactionUpdate<ƒ>>
30
+ }
31
+
32
+ export function transaction<ƒ extends ƒn>(
33
+ options: TransactionOptions<ƒ>
34
+ ): TransactionToken<ƒ> {
35
+ return transaction__INTERNAL(options)
36
+ }
37
+
38
+ export const runTransaction =
39
+ <ƒ extends ƒn>(token: TransactionToken<ƒ>, store: Store = IMPLICIT.STORE) =>
40
+ (...parameters: Parameters<ƒ>): ReturnType<ƒ> =>
41
+ withdraw(token, store).run(...parameters)