Skip to content

Commit 8f241ba

Browse files
committed
ok this basically works
1 parent 4f01727 commit 8f241ba

File tree

8 files changed

+127
-135
lines changed

8 files changed

+127
-135
lines changed

packages/plexus-core/src/action.ts

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -111,21 +111,21 @@ export type InnerFunction<ResultFn extends FunctionType> = ResultFn extends (
111111
// export type PlexusAction = <ReturnData=FunctionType>(fn: FunctionType) => (...args: any) => ReturnData | Promise<ReturnData>
112112
export type PlexusAction = typeof _action
113113

114-
export function _action<Response>(
114+
export function _action<Response, Fn extends FunctionType>(
115115
instance: () => PlexusInstance,
116-
fn: (...args: FunctionArgs) => Response,
116+
fn: ((...args: FunctionArgs) => Response) & Fn,
117117
batched?: boolean
118118
): (...args: InnerFunctionArgs) => Response
119119

120-
export function _action<Response>(
120+
export function _action<Response, Fn extends FunctionType>(
121121
instance: () => PlexusInstance,
122-
fn: (...args: FunctionArgs) => Promise<Response>,
122+
fn: ((...args: FunctionArgs) => Promise<Response>) & Fn,
123123
batched?: boolean
124124
): (...args: InnerFunctionArgs) => Promise<Response>
125125

126-
export function _action<Response>(
126+
export function _action<Response, Fn extends FunctionType>(
127127
instance: () => PlexusInstance,
128-
fn: (...args: FunctionArgs) => Promise<Response> | Response,
128+
fn: ((...args: FunctionArgs) => Promise<Response> | Response) & Fn,
129129
batched?: boolean
130130
) {
131131
const helpers = new PlexusActionHelpers(instance)
@@ -153,7 +153,6 @@ export function _action<Response>(
153153
})
154154
}
155155
}
156-
console.log('hewhewhewhewhewh', batched, args, 'hewhewhewhewhewh')
157156
// if the action is batched, run it in a batch
158157
if (batched) {
159158
return instance().runtime.batch(() => fn(helpers.hooks, ...args))
@@ -164,6 +163,7 @@ export function _action<Response>(
164163
// only return the error if there is no handler
165164

166165
if (!helpers.catchError && !instance()._globalCatch) {
166+
console.log('error caught but returning', e)
167167
if (e instanceof PlexusError) throw e
168168
if (e instanceof Error) {
169169
throw new PlexusError(
@@ -172,6 +172,7 @@ export function _action<Response>(
172172
)
173173
}
174174
}
175+
console.log('error caught', e)
175176
helpers.runErrorHandlers(e)
176177

177178
// otherwise run the handler and return null
@@ -184,7 +185,7 @@ export function _action<Response>(
184185
}
185186
}
186187
// return the proxy function
187-
return newAction
188+
return newAction as InnerFunction<Fn>
188189
// return proxyFn as InnerFunction<Fn>
189190

190191
// const newAction = async (...args) => {
@@ -222,10 +223,12 @@ export function _action<Response>(
222223
* @param fn The Plexus action function to run
223224
* @returns The intended return value of fn, or null if an error is caught
224225
*/
225-
export function action<Response>(fn: (...args: FunctionArgs) => Response)
226+
export function action<Response>(
227+
fn: (...args: FunctionArgs) => Response
228+
): (...args: InnerFunctionArgs) => Response
226229
export function action<Response>(
227230
fn: (...args: FunctionArgs) => Promise<Response>
228-
)
231+
): (...args: InnerFunctionArgs) => Promise<Response>
229232
export function action<Response>(
230233
fn: (...args: FunctionArgs) => Promise<Response> | Response
231234
) {

packages/plexus-core/src/instance/runtime.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -238,12 +238,13 @@ export class RuntimeInstance {
238238
}
239239
// stop storing changes and emit the changes
240240
this.batching = false
241+
const unhalt = this.engine.halt()
241242
// call all the pending functions and clear the array
242243
this.batchedCalls.forEach((pendingFn) => pendingFn())
243244
this.batchedCalls.length = 0
244245

245246
// release the reactivity engine
246-
// unhalt()
247+
unhalt()
247248

248249
this.instance().runtime.log('info', 'Batch function completed!')
249250
}

packages/plexus-core/src/scope.ts

Lines changed: 12 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -26,10 +26,7 @@ export class Scope {
2626
// private _internalStore: PlexusScopeStore
2727
public instance: () => PlexusInstance
2828

29-
constructor(
30-
public name: string,
31-
config?: PlexusScopeConfig
32-
) {
29+
constructor(public name: string, config?: PlexusScopeConfig) {
3330
if (!name || name.length === 0) {
3431
throw new Error('Scope name is required')
3532
}
@@ -93,17 +90,17 @@ export class Scope {
9390
* @param fn The Plexus action function to run
9491
* @returns The intended return value of fn, or null if an error is caught
9592
*/
96-
action<Fn extends FunctionType>(fn: Fn) {
97-
return _action<Fn>(this.instance, fn)
98-
}
99-
/**
100-
* Generate a Plexus Action
101-
* @param fn The Plexus action function to run
102-
* @returns The intended return value of fn, or null if an error is caught
103-
*/
104-
batchAction<Fn extends FunctionType>(fn: Fn) {
105-
return _action<Fn>(this.instance, fn, true)
106-
}
93+
// action<Fn extends FunctionType>(fn: Fn) {
94+
// return _action<Fn>(this.instance, fn)
95+
// }
96+
// /**
97+
// * Generate a Plexus Action
98+
// * @param fn The Plexus action function to run
99+
// * @returns The intended return value of fn, or null if an error is caught
100+
// */
101+
// batchAction<Fn extends FunctionType>(fn: Fn) {
102+
// return _action<Fn>(this.instance, fn, true)
103+
// }
107104
/**
108105
* Run a function. During that function's execution, any state changes will be batched and only applied once the function has finished.
109106
* @param fn The function to run in a batch

packages/plexus-utils/src/shared/index.ts

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,12 @@ export const genUID = () =>
66
Math.random().toString(36).substring(2, 15) +
77
Math.random().toString(36).substring(2, 15)
88

9-
export const isAsyncFunction = <ReturnedValue>(
10-
fn: (...args: any[]) => ReturnedValue | Promise<ReturnedValue>
11-
): fn is () => Promise<ReturnedValue> =>
9+
export const isAsyncFunction = <
10+
ReturnedValue,
11+
Args extends Array<unknown> = any[]
12+
>(
13+
fn: (...args: Args) => ReturnedValue | Promise<ReturnedValue>
14+
): fn is (...args: Args) => Promise<ReturnedValue> =>
1215
typeof fn === 'function' &&
1316
(fn.constructor.name === 'AsyncFunction' ||
1417
fn[Symbol.toStringTag] === 'AsyncFunction')

tests/action.test.ts

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -73,14 +73,14 @@ describe('Testing Action Function', () => {
7373
})
7474

7575
test(`Can handle async errors`, async () => {
76+
let counter = 0
7677
const myAction = action(async ({ onCatch }) => {
77-
onCatch(() => {
78-
console.log('error caught successfully!')
79-
})
80-
return await new Promise((resolve, reject) => {
81-
setTimeout(() => reject(new Error('test error')), 100)
82-
})
78+
onCatch(console.error)
79+
counter++
80+
if (counter === 2) throw new Error('test error')
8381
})
82+
83+
await myAction()
8484
const data = await myAction()
8585
expect(data).toBeDefined()
8686
})

tests/efficiency.test.ts

Lines changed: 38 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ const users1kRelated = Array.from(
2525
id: randUuid(),
2626
firstName: randFirstName(),
2727
appointmentId: randUuid(),
28-
}) as User
28+
} as User)
2929
)
3030

3131
const appointments1kRelated = users1kRelated.map(
@@ -35,7 +35,7 @@ const appointments1kRelated = users1kRelated.map(
3535
userId: user.id,
3636
date: randFutureDate().getTime(),
3737
name: randBook().title,
38-
}) as Appointment
38+
} as Appointment)
3939
)
4040

4141
// check the .cache directory for the generated data. If it doesn't exist, it will be generated. Need users1k.json, users10k.json, users10kRelated.json, appointments10kRelated.json
@@ -51,52 +51,40 @@ afterEach(() => {
5151
})
5252

5353
describe('Efficiency tests for ', () => {
54-
// test('The speed of a plexus collection collecting more than a thousand randomly generated objects into multiple groups', () => {
55-
// instance({ logLevel: 'debug' })
56-
// console.log('Starting test...')
57-
// console.log('items in collection:', users1k.length)
58-
// usersLite.collect(users1k, ['firstNames'])
59-
// console.log('items in collection:', usersLite.value.length)
60-
// expect(usersLite.value.length).toBe(1000)
61-
// expect(usersLite.groups.firstNames.value.length).toBe(1000)
62-
// instance({ logLevel: undefined })
63-
// })
64-
// test('Testing the same as above but with an absurd amount of data', () => {
65-
// instance({ logLevel: 'debug' })
66-
// console.log('Starting test...')
67-
// console.log('items in collection:', users10k.length)
68-
// usersLite.collect(users10k, ['firstNames'])
69-
// console.log('items in collection:', usersLite.value.length)
70-
// // const group1 = collectionInstance.group('appointmentId')
71-
// // const group2 = collectionInstance.group('name')
72-
// // expect(group1.value.length).toBe(1000)
73-
// // expect(group2.value.length).toBe(1000)
74-
// instance({ logLevel: undefined })
75-
// })
76-
// test('An absurd amount of related data', () => {
77-
// instance({ logLevel: 'debug' })
78-
// console.log('Starting test...')
79-
// console.log('items in collection:', users10k.length)
80-
// users.collect(users1kRelated, ['main'])
81-
// appointments.collect(appointments1kRelated, ['main'])
82-
// console.log('items in collection:', users.value.length)
83-
// // const group1 = collectionInstance.group('appointmentId')
84-
// // const group2 = collectionInstance.group('name')
85-
// // expect(group1.value.length).toBe(1000)
86-
// // expect(group2.value.length).toBe(1000)
87-
// instance({ logLevel: undefined })
88-
// })
89-
// test('An absurd amount of related data', () => {
90-
// instance({ logLevel: 'debug' })
91-
// console.log('Starting test...')
92-
// console.log('items in collection:', users10k.length)
93-
// users.collect(users1kRelated, ['main'])
94-
// appointments.collect(appointments1kRelated, ['main'])
95-
// console.log('items in collection:', users.value.length)
96-
// // const group1 = collectionInstance.group('appointmentId')
97-
// // const group2 = collectionInstance.group('name')
98-
// // expect(group1.value.length).toBe(1000)
99-
// // expect(group2.value.length).toBe(1000)
100-
// instance({ logLevel: undefined })
101-
// })
54+
test('The speed of a plexus collection collecting more than a thousand randomly generated objects into multiple groups', () => {
55+
instance({ logLevel: 'debug' })
56+
console.log('Starting test...')
57+
console.log('items in collection:', users1k.length)
58+
usersLite.collect(users1k, ['firstNames'])
59+
console.log('items in collection:', usersLite.value.length)
60+
expect(usersLite.value.length).toBe(1000)
61+
expect(usersLite.groups.firstNames.value.length).toBe(1000)
62+
63+
instance({ logLevel: undefined })
64+
})
65+
test('Testing the same as above but with an absurd amount of data', () => {
66+
instance({ logLevel: 'debug' })
67+
console.log('Starting test...')
68+
console.log('items in collection:', users10k.length)
69+
usersLite.collect(users10k, ['firstNames'])
70+
console.log('items in collection:', usersLite.value.length)
71+
// const group1 = collectionInstance.group('appointmentId')
72+
// const group2 = collectionInstance.group('name')
73+
// expect(group1.value.length).toBe(1000)
74+
// expect(group2.value.length).toBe(1000)
75+
instance({ logLevel: undefined })
76+
})
77+
test('An absurd amount of related data', () => {
78+
instance({ logLevel: 'debug' })
79+
console.log('Starting test...')
80+
console.log('items in collection:', users10k.length)
81+
users.collect(users1kRelated, ['main'])
82+
appointments.collect(appointments1kRelated, ['main'])
83+
console.log('items in collection:', users.value.length)
84+
// const group1 = collectionInstance.group('appointmentId')
85+
// const group2 = collectionInstance.group('name')
86+
// expect(group1.value.length).toBe(1000)
87+
// expect(group2.value.length).toBe(1000)
88+
instance({ logLevel: undefined })
89+
})
10290
})

tests/test-utils.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ export const uniqueGroups = collection<UserLiteExplicitIdName>({
8888
uniqueGroups: true,
8989
}).createSelector('batched')
9090

91-
export const DEFAULT_DECAY_RATE = 12_000
91+
export const DEFAULT_DECAY_RATE = 1_000
9292
export const decayingUsers = collection<UserLiteExplicitIdName>({
9393
primaryKey: 'userId',
9494
name: 'userslite',

tests/timed.test.ts

Lines changed: 49 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -1,53 +1,53 @@
1-
import { describe, test } from 'vitest'
1+
import { describe, expect, test } from 'vitest'
22
import { DEFAULT_DECAY_RATE, decayingUsers } from './test-utils'
33

44
describe('Ephemeral Collection data', () => {
5-
// test(
6-
// 'Does decaying data work?',
7-
// (ctx) =>
8-
// new Promise((resolve) => {
9-
// decayingUsers.collect({ firstName: 'Bill', userId: '0' })
10-
// expect(decayingUsers.value.length).toBe(1)
11-
// expect(decayingUsers.value[0].firstName).toBe('Bill')
12-
// expect(decayingUsers.value[0].userId).toBe('0')
13-
// setTimeout(() => {
14-
// expect(decayingUsers.value.length).toBe(0)
15-
// console.log('done! Thing is decayed!')
16-
// resolve(true)
17-
// }, DEFAULT_DECAY_RATE + 10)
18-
// }),
19-
// DEFAULT_DECAY_RATE + 100
20-
// )
21-
// test(
22-
// 'Does decaying data refresh on set?',
23-
// (ctx) =>
24-
// new Promise((resolve) => {
25-
// decayingUsers.collect({ firstName: 'Bill', userId: '0' })
26-
// expect(decayingUsers.value.length).toBe(1)
27-
// expect(decayingUsers.value[0].firstName).toBe('Bill')
28-
// expect(decayingUsers.value[0].userId).toBe('0')
29-
// // recollecting should reset the decay timer
30-
// setTimeout(() => {
31-
// expect(decayingUsers.value.length).toBe(1)
32-
// decayingUsers.collect({ firstName: 'Bill', userId: '0' })
33-
// }, DEFAULT_DECAY_RATE - 10)
34-
// // so if we wait a bit, it should still be there
35-
// setTimeout(() => {
36-
// console.log('wtfff')
37-
// expect(decayingUsers.value.length).toBe(1)
38-
// }, DEFAULT_DECAY_RATE + 10)
39-
// // and then it should decay past the decay rate
40-
// setTimeout(
41-
// () => {
42-
// expect(decayingUsers.value.length).toBe(0)
43-
// console.log('done! Thing is decayed!')
44-
// resolve(true)
45-
// },
46-
// DEFAULT_DECAY_RATE * 2 + 10
47-
// )
48-
// }),
49-
// {
50-
// timeout: DEFAULT_DECAY_RATE * 2 + 100,
51-
// }
52-
// )
5+
test(
6+
'Does decaying data work?',
7+
(ctx) =>
8+
new Promise((resolve) => {
9+
decayingUsers.collect({ firstName: 'Bill', userId: '0' })
10+
expect(decayingUsers.value.length).toBe(1)
11+
expect(decayingUsers.value[0].firstName).toBe('Bill')
12+
expect(decayingUsers.value[0].userId).toBe('0')
13+
setTimeout(() => {
14+
expect(decayingUsers.value.length).toBe(0)
15+
console.log('done! Thing is decayed!')
16+
resolve(true)
17+
}, DEFAULT_DECAY_RATE + 10)
18+
}),
19+
DEFAULT_DECAY_RATE + 100
20+
)
21+
test(
22+
'Does decaying data refresh on set?',
23+
(ctx) =>
24+
new Promise((resolve) => {
25+
decayingUsers.collect({ firstName: 'Bill', userId: '0' })
26+
expect(decayingUsers.value.length).toBe(1)
27+
expect(decayingUsers.value[0].firstName).toBe('Bill')
28+
expect(decayingUsers.value[0].userId).toBe('0')
29+
// recollecting should reset the decay timer
30+
setTimeout(() => {
31+
expect(decayingUsers.value.length).toBe(1)
32+
decayingUsers.collect({ firstName: 'Bill', userId: '0' })
33+
}, DEFAULT_DECAY_RATE - 10)
34+
// so if we wait a bit, it should still be there
35+
setTimeout(() => {
36+
console.log('wtfff')
37+
expect(decayingUsers.value.length).toBe(1)
38+
}, DEFAULT_DECAY_RATE + 10)
39+
// and then it should decay past the decay rate
40+
setTimeout(
41+
() => {
42+
expect(decayingUsers.value.length).toBe(0)
43+
console.log('done! Thing is decayed!')
44+
resolve(true)
45+
},
46+
DEFAULT_DECAY_RATE * 2 + 10
47+
)
48+
}),
49+
{
50+
timeout: DEFAULT_DECAY_RATE * 2 + 100,
51+
}
52+
)
5353
})

0 commit comments

Comments
 (0)