teamplay 0.4.0-alpha.95 → 0.4.0-alpha.96
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/react/renderAttemptDestroyer.js +24 -15
- package/react/trapRender.js +5 -2
- package/react/useSub.js +3 -2
- package/react/useSuspendMemo.js +2 -2
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "teamplay",
|
|
3
|
-
"version": "0.4.0-alpha.
|
|
3
|
+
"version": "0.4.0-alpha.96",
|
|
4
4
|
"description": "Full-stack signals ORM with multiplayer",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "index.js",
|
|
@@ -83,5 +83,5 @@
|
|
|
83
83
|
]
|
|
84
84
|
},
|
|
85
85
|
"license": "MIT",
|
|
86
|
-
"gitHead": "
|
|
86
|
+
"gitHead": "78f33dc002740b425f3a056fad5b7e780a34219c"
|
|
87
87
|
}
|
|
@@ -1,37 +1,46 @@
|
|
|
1
1
|
class RenderAttemptDestroyer {
|
|
2
2
|
constructor () {
|
|
3
3
|
this.fns = []
|
|
4
|
-
this.
|
|
4
|
+
this.compatAttemptCleanupArmed = false
|
|
5
|
+
this.suspenseGateArmed = false
|
|
5
6
|
}
|
|
6
7
|
|
|
7
8
|
add (fn, { compat = false } = {}) {
|
|
8
9
|
if (typeof fn !== 'function') return
|
|
9
10
|
this.fns.push(fn)
|
|
10
|
-
if (compat) this.
|
|
11
|
+
if (compat) this.compatAttemptCleanupArmed = true
|
|
11
12
|
}
|
|
12
13
|
|
|
13
|
-
|
|
14
|
-
this.
|
|
14
|
+
armCompatAttemptCleanup () {
|
|
15
|
+
this.compatAttemptCleanupArmed = true
|
|
15
16
|
}
|
|
16
17
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
return undefined
|
|
21
|
-
}
|
|
18
|
+
armSuspenseGate () {
|
|
19
|
+
this.suspenseGateArmed = true
|
|
20
|
+
}
|
|
22
21
|
|
|
23
|
-
|
|
22
|
+
consumeThenableHandling () {
|
|
23
|
+
const shouldRunAttemptCleanup = this.compatAttemptCleanupArmed && this.fns.length > 0
|
|
24
|
+
const shouldKeepShellAlive = this.suspenseGateArmed || shouldRunAttemptCleanup
|
|
25
|
+
let destroyAttempt
|
|
26
|
+
if (shouldRunAttemptCleanup) {
|
|
27
|
+
const fns = [...this.fns]
|
|
28
|
+
destroyAttempt = async () => {
|
|
29
|
+
await Promise.allSettled(fns.map(fn => fn()))
|
|
30
|
+
fns.length = 0
|
|
31
|
+
}
|
|
32
|
+
}
|
|
24
33
|
this.reset()
|
|
25
|
-
return
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
fns.length = 0
|
|
34
|
+
return {
|
|
35
|
+
shouldKeepShellAlive,
|
|
36
|
+
destroyAttempt
|
|
29
37
|
}
|
|
30
38
|
}
|
|
31
39
|
|
|
32
40
|
reset () {
|
|
33
41
|
this.fns.length = 0
|
|
34
|
-
this.
|
|
42
|
+
this.compatAttemptCleanupArmed = false
|
|
43
|
+
this.suspenseGateArmed = false
|
|
35
44
|
}
|
|
36
45
|
}
|
|
37
46
|
|
package/react/trapRender.js
CHANGED
|
@@ -24,8 +24,11 @@ export default function trapRender ({ render, cache, destroy, componentId }) {
|
|
|
24
24
|
destroyed = true
|
|
25
25
|
throw err
|
|
26
26
|
}
|
|
27
|
-
const
|
|
28
|
-
|
|
27
|
+
const {
|
|
28
|
+
shouldKeepShellAlive,
|
|
29
|
+
destroyAttempt
|
|
30
|
+
} = renderAttemptDestroyer.consumeThenableHandling()
|
|
31
|
+
if (shouldKeepShellAlive) {
|
|
29
32
|
throw Promise.resolve(err).then(() => destroyAttempt?.())
|
|
30
33
|
}
|
|
31
34
|
|
package/react/useSub.js
CHANGED
|
@@ -158,6 +158,7 @@ function maybeThrottle (promise) {
|
|
|
158
158
|
function registerCompatAttemptCleanup (signal, params) {
|
|
159
159
|
// Compat hooks don't build per-hook init objects like Racer.
|
|
160
160
|
// We still need a marker so trapRender can defer observer-shell cleanup
|
|
161
|
-
//
|
|
162
|
-
|
|
161
|
+
// only when a real attempt cleanup exists.
|
|
162
|
+
// This path must not arm suspense-gate keep-alive by itself.
|
|
163
|
+
renderAttemptDestroyer.armCompatAttemptCleanup()
|
|
163
164
|
}
|
package/react/useSuspendMemo.js
CHANGED
|
@@ -28,7 +28,7 @@ export default function useSuspendMemo (factory, deps) {
|
|
|
28
28
|
if (entry.status === 'done') return entry.value
|
|
29
29
|
if (entry.status === 'pending') {
|
|
30
30
|
markCompatComponent(componentId)
|
|
31
|
-
renderAttemptDestroyer.
|
|
31
|
+
renderAttemptDestroyer.armSuspenseGate()
|
|
32
32
|
throw entry.promise
|
|
33
33
|
}
|
|
34
34
|
|
|
@@ -47,7 +47,7 @@ export default function useSuspendMemo (factory, deps) {
|
|
|
47
47
|
entry.status = 'pending'
|
|
48
48
|
entry.promise = promise
|
|
49
49
|
markCompatComponent(componentId)
|
|
50
|
-
renderAttemptDestroyer.
|
|
50
|
+
renderAttemptDestroyer.armSuspenseGate()
|
|
51
51
|
throw promise
|
|
52
52
|
}
|
|
53
53
|
}
|