@plastic-js/plastic 1.0.1 → 1.0.2
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/package.json +2 -2
- package/src/async.js +88 -0
- package/src/computation-context.js +6 -0
- package/src/index.js +2 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@plastic-js/plastic",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.2",
|
|
4
4
|
"main": "src/index.js",
|
|
5
5
|
"access": "public",
|
|
6
6
|
"sideEffects": false,
|
|
@@ -57,7 +57,7 @@
|
|
|
57
57
|
"@babel/core": "^7.29.0",
|
|
58
58
|
"@babel/preset-react": "^7.28.5",
|
|
59
59
|
"@testing-library/jest-dom": "^6.9.1",
|
|
60
|
-
"babel-preset-plastic": "^0.1.
|
|
60
|
+
"babel-preset-plastic": "^0.1.1",
|
|
61
61
|
"@vitejs/plugin-react": "^6.0.2",
|
|
62
62
|
"@vitejs/plugin-vue": "^6.0.7",
|
|
63
63
|
"eslint": "^9.39.2",
|
package/src/async.js
ADDED
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import { createSignal } from './reactivity.js'
|
|
2
|
+
|
|
3
|
+
const normalizeService = (service)=> {
|
|
4
|
+
if (typeof service === 'function'){
|
|
5
|
+
return service
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
if (service instanceof Promise){
|
|
9
|
+
return ()=> service
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
throw new TypeError('createAsync expects a Promise or a function returning a Promise')
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
const createAsync = (service)=> {
|
|
16
|
+
const runner = normalizeService(service)
|
|
17
|
+
const isLoading = createSignal(false)
|
|
18
|
+
const data = createSignal(undefined)
|
|
19
|
+
const error = createSignal(null)
|
|
20
|
+
let latestRunId = 0
|
|
21
|
+
|
|
22
|
+
const run = (...args)=> {
|
|
23
|
+
const runId = ++latestRunId
|
|
24
|
+
isLoading(true)
|
|
25
|
+
error(null)
|
|
26
|
+
|
|
27
|
+
let promise
|
|
28
|
+
try {
|
|
29
|
+
promise = runner(...args)
|
|
30
|
+
} catch(err){
|
|
31
|
+
error(err)
|
|
32
|
+
isLoading(false)
|
|
33
|
+
return Promise.reject(err)
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
if (!(promise instanceof Promise)){
|
|
37
|
+
const typeError = new TypeError('createAsync runner must return a Promise')
|
|
38
|
+
error(typeError)
|
|
39
|
+
isLoading(false)
|
|
40
|
+
return Promise.reject(typeError)
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
return promise
|
|
44
|
+
.then((value)=> {
|
|
45
|
+
if (runId !== latestRunId){
|
|
46
|
+
return value
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
data(value)
|
|
50
|
+
error(null)
|
|
51
|
+
return value
|
|
52
|
+
})
|
|
53
|
+
.catch((err)=> {
|
|
54
|
+
if (runId === latestRunId){
|
|
55
|
+
error(err)
|
|
56
|
+
}
|
|
57
|
+
throw err
|
|
58
|
+
})
|
|
59
|
+
.finally(()=> {
|
|
60
|
+
if (runId === latestRunId){
|
|
61
|
+
isLoading(false)
|
|
62
|
+
}
|
|
63
|
+
})
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
const cancel = ()=> {
|
|
67
|
+
if (!isLoading()){
|
|
68
|
+
return
|
|
69
|
+
}
|
|
70
|
+
latestRunId++
|
|
71
|
+
isLoading(false)
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
// Default behavior: trigger once on creation for immediate data fetch.
|
|
75
|
+
run().catch(()=> {})
|
|
76
|
+
|
|
77
|
+
return {
|
|
78
|
+
isLoading,
|
|
79
|
+
data,
|
|
80
|
+
error,
|
|
81
|
+
run,
|
|
82
|
+
cancel,
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
export {
|
|
87
|
+
createAsync,
|
|
88
|
+
}
|
|
@@ -1,3 +1,9 @@
|
|
|
1
|
+
// Shared module-level state for the currently running computation.
|
|
2
|
+
// Extracted into its own module so the two consumers can share the same
|
|
3
|
+
// reference without forming a circular import between them:
|
|
4
|
+
// - the computation runner writes it before/after executing a tracked fn
|
|
5
|
+
// - the signal/state layer reads it when a signal is invoked (e.g.
|
|
6
|
+
// `signal()`) to register the running computation as a dependency
|
|
1
7
|
let currentComputation = null
|
|
2
8
|
|
|
3
9
|
const getCurrentComputation = ()=> currentComputation
|
package/src/index.js
CHANGED
|
@@ -39,6 +39,7 @@ import {
|
|
|
39
39
|
useSearchParams,
|
|
40
40
|
} from './router.js'
|
|
41
41
|
import { batch } from './reactivity.js'
|
|
42
|
+
import { createAsync } from './async.js'
|
|
42
43
|
import { mergeProps } from './merge-props.js'
|
|
43
44
|
import { createSplitProps, splitProps } from './split-props.js'
|
|
44
45
|
|
|
@@ -80,6 +81,7 @@ export {
|
|
|
80
81
|
createContext,
|
|
81
82
|
useContext,
|
|
82
83
|
batch,
|
|
84
|
+
createAsync,
|
|
83
85
|
mergeProps,
|
|
84
86
|
splitProps,
|
|
85
87
|
createSplitProps,
|