@vidact/runtime 0.2.0-beta.0 → 0.2.0-beta.5

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.
Files changed (244) hide show
  1. package/CHANGELOG.md +52 -0
  2. package/README.md +1 -1
  3. package/dist/actions.d.ts +32 -30
  4. package/dist/actions.d.ts.map +1 -1
  5. package/dist/actions.js +251 -266
  6. package/dist/actions.js.map +1 -1
  7. package/dist/async.d.ts +20 -17
  8. package/dist/async.d.ts.map +1 -1
  9. package/dist/async.js +18 -17
  10. package/dist/async.js.map +1 -1
  11. package/dist/compiled/async-resource.d.ts +9 -6
  12. package/dist/compiled/async-resource.d.ts.map +1 -1
  13. package/dist/compiled/async-resource.js +69 -77
  14. package/dist/compiled/async-resource.js.map +1 -1
  15. package/dist/compiled/core.d.ts +136 -147
  16. package/dist/compiled/core.d.ts.map +1 -1
  17. package/dist/compiled/core.js +2672 -2985
  18. package/dist/compiled/core.js.map +1 -1
  19. package/dist/compiled/types.d.ts +44 -56
  20. package/dist/compiled/types.d.ts.map +1 -1
  21. package/dist/compiled/types.js +10 -6
  22. package/dist/compiled/types.js.map +1 -1
  23. package/dist/compiled/validation.d.ts +4 -1
  24. package/dist/compiled/validation.d.ts.map +1 -1
  25. package/dist/compiled/validation.js +17 -20
  26. package/dist/compiled/validation.js.map +1 -1
  27. package/dist/component-spread.d.ts +5 -3
  28. package/dist/component-spread.d.ts.map +1 -1
  29. package/dist/component-spread.js +49 -67
  30. package/dist/component-spread.js.map +1 -1
  31. package/dist/concurrent.d.ts +20 -18
  32. package/dist/concurrent.d.ts.map +1 -1
  33. package/dist/concurrent.js +191 -210
  34. package/dist/concurrent.js.map +1 -1
  35. package/dist/direct-dom.d.ts +17 -12
  36. package/dist/direct-dom.d.ts.map +1 -1
  37. package/dist/direct-dom.js +187 -221
  38. package/dist/direct-dom.js.map +1 -1
  39. package/dist/dom/attributes.d.ts +9 -6
  40. package/dist/dom/attributes.d.ts.map +1 -1
  41. package/dist/dom/attributes.js +65 -47
  42. package/dist/dom/attributes.js.map +1 -1
  43. package/dist/dom/events.d.ts +5 -2
  44. package/dist/dom/events.d.ts.map +1 -1
  45. package/dist/dom/events.js +53 -65
  46. package/dist/dom/events.js.map +1 -1
  47. package/dist/dom/forms.d.ts +9 -6
  48. package/dist/dom/forms.d.ts.map +1 -1
  49. package/dist/dom/forms.js +152 -198
  50. package/dist/dom/forms.js.map +1 -1
  51. package/dist/dom/intrinsic.d.ts +17 -15
  52. package/dist/dom/intrinsic.d.ts.map +1 -1
  53. package/dist/dom/intrinsic.js +48 -50
  54. package/dist/dom/intrinsic.js.map +1 -1
  55. package/dist/dom/namespace.d.ts +4 -1
  56. package/dist/dom/namespace.d.ts.map +1 -1
  57. package/dist/dom/namespace.js +25 -28
  58. package/dist/dom/namespace.js.map +1 -1
  59. package/dist/dom/namespaces.d.ts +11 -8
  60. package/dist/dom/namespaces.d.ts.map +1 -1
  61. package/dist/dom/namespaces.js +14 -12
  62. package/dist/dom/namespaces.js.map +1 -1
  63. package/dist/dom/properties.d.ts +18 -16
  64. package/dist/dom/properties.d.ts.map +1 -1
  65. package/dist/dom/properties.js +273 -296
  66. package/dist/dom/properties.js.map +1 -1
  67. package/dist/dom/style-properties.d.ts +4 -1
  68. package/dist/dom/style-properties.d.ts.map +1 -1
  69. package/dist/dom/style-properties.js +49 -45
  70. package/dist/dom/style-properties.js.map +1 -1
  71. package/dist/dom/styles.d.ts +5 -2
  72. package/dist/dom/styles.d.ts.map +1 -1
  73. package/dist/dom/styles.js +47 -67
  74. package/dist/dom/styles.js.map +1 -1
  75. package/dist/dom-forms.d.ts +4 -1
  76. package/dist/dom-forms.d.ts.map +1 -1
  77. package/dist/dom-forms.js +16 -13
  78. package/dist/dom-forms.js.map +1 -1
  79. package/dist/dom-styles.d.ts +4 -1
  80. package/dist/dom-styles.d.ts.map +1 -1
  81. package/dist/dom-styles.js +10 -7
  82. package/dist/dom-styles.js.map +1 -1
  83. package/dist/framework-hydrate.d.ts +20 -17
  84. package/dist/framework-hydrate.d.ts.map +1 -1
  85. package/dist/framework-hydrate.js +128 -146
  86. package/dist/framework-hydrate.js.map +1 -1
  87. package/dist/framework-protocol.d.ts +27 -25
  88. package/dist/framework-protocol.d.ts.map +1 -1
  89. package/dist/framework-protocol.js +173 -211
  90. package/dist/framework-protocol.js.map +1 -1
  91. package/dist/framework.d.ts +34 -32
  92. package/dist/framework.d.ts.map +1 -1
  93. package/dist/framework.js +74 -93
  94. package/dist/framework.js.map +1 -1
  95. package/dist/hydrate.d.ts +11 -8
  96. package/dist/hydrate.d.ts.map +1 -1
  97. package/dist/hydrate.js +13 -9
  98. package/dist/hydrate.js.map +1 -1
  99. package/dist/hydration-bridge.d.ts +70 -58
  100. package/dist/hydration-bridge.d.ts.map +1 -1
  101. package/dist/hydration-bridge.js +77 -66
  102. package/dist/hydration-bridge.js.map +1 -1
  103. package/dist/hydration.d.ts +54 -28
  104. package/dist/hydration.d.ts.map +1 -1
  105. package/dist/hydration.js +450 -463
  106. package/dist/hydration.js.map +1 -1
  107. package/dist/index.d.ts +13 -13
  108. package/dist/index.js +11 -13
  109. package/dist/indexed-list.d.ts +8 -5
  110. package/dist/indexed-list.d.ts.map +1 -1
  111. package/dist/indexed-list.js +14 -7
  112. package/dist/indexed-list.js.map +1 -1
  113. package/dist/jsx-runtime.d.ts +10 -8
  114. package/dist/jsx-runtime.d.ts.map +1 -1
  115. package/dist/jsx-runtime.js +28 -23
  116. package/dist/jsx-runtime.js.map +1 -1
  117. package/dist/keyed-list.d.ts +13 -14
  118. package/dist/keyed-list.d.ts.map +1 -1
  119. package/dist/keyed-list.js +132 -160
  120. package/dist/keyed-list.js.map +1 -1
  121. package/dist/metadata.d.ts +6 -3
  122. package/dist/metadata.d.ts.map +1 -1
  123. package/dist/metadata.js +131 -164
  124. package/dist/metadata.js.map +1 -1
  125. package/dist/nested-prop.d.ts +4 -2
  126. package/dist/nested-prop.d.ts.map +1 -1
  127. package/dist/nested-prop.js +17 -16
  128. package/dist/nested-prop.js.map +1 -1
  129. package/dist/profiling.d.ts +11 -8
  130. package/dist/profiling.d.ts.map +1 -1
  131. package/dist/profiling.js +17 -17
  132. package/dist/profiling.js.map +1 -1
  133. package/dist/protocol.d.ts +5 -2
  134. package/dist/protocol.d.ts.map +1 -1
  135. package/dist/protocol.js +8 -5
  136. package/dist/protocol.js.map +1 -1
  137. package/dist/raw-html.d.ts +5 -2
  138. package/dist/raw-html.d.ts.map +1 -1
  139. package/dist/raw-html.js +86 -146
  140. package/dist/raw-html.js.map +1 -1
  141. package/dist/ref.d.ts +8 -3
  142. package/dist/ref.d.ts.map +1 -1
  143. package/dist/ref.js +10 -2
  144. package/dist/ref.js.map +1 -1
  145. package/dist/renderable-protocol.d.ts +26 -8
  146. package/dist/renderable-protocol.d.ts.map +1 -1
  147. package/dist/renderable-protocol.js +30 -9
  148. package/dist/renderable-protocol.js.map +1 -1
  149. package/dist/renderable.d.ts +27 -22
  150. package/dist/renderable.d.ts.map +1 -1
  151. package/dist/renderable.js +141 -133
  152. package/dist/renderable.js.map +1 -1
  153. package/dist/retained-ui.d.ts +9 -6
  154. package/dist/retained-ui.d.ts.map +1 -1
  155. package/dist/retained-ui.js +12 -10
  156. package/dist/retained-ui.js.map +1 -1
  157. package/dist/root.d.ts +18 -15
  158. package/dist/root.d.ts.map +1 -1
  159. package/dist/root.js +73 -85
  160. package/dist/root.js.map +1 -1
  161. package/dist/scheduler.d.ts +10 -8
  162. package/dist/scheduler.d.ts.map +1 -1
  163. package/dist/scheduler.js +97 -105
  164. package/dist/scheduler.js.map +1 -1
  165. package/dist/server-framework.d.ts +45 -42
  166. package/dist/server-framework.d.ts.map +1 -1
  167. package/dist/server-framework.js +209 -217
  168. package/dist/server-framework.js.map +1 -1
  169. package/dist/server.d.ts +130 -128
  170. package/dist/server.d.ts.map +1 -1
  171. package/dist/server.js +603 -710
  172. package/dist/server.js.map +1 -1
  173. package/dist/shared/promise.d.ts +6 -3
  174. package/dist/shared/promise.d.ts.map +1 -1
  175. package/dist/shared/promise.js +21 -19
  176. package/dist/shared/promise.js.map +1 -1
  177. package/dist/source-mask.d.ts +9 -6
  178. package/dist/source-mask.d.ts.map +1 -1
  179. package/dist/source-mask.js +45 -63
  180. package/dist/source-mask.js.map +1 -1
  181. package/dist/spread.d.ts +5 -2
  182. package/dist/spread.d.ts.map +1 -1
  183. package/dist/spread.js +79 -99
  184. package/dist/spread.js.map +1 -1
  185. package/dist/state-slot.d.ts +18 -15
  186. package/dist/state-slot.d.ts.map +1 -1
  187. package/dist/state-slot.js +43 -42
  188. package/dist/state-slot.js.map +1 -1
  189. package/dist/testing.d.ts +9 -6
  190. package/dist/testing.d.ts.map +1 -1
  191. package/dist/testing.js +16 -12
  192. package/dist/testing.js.map +1 -1
  193. package/package.json +8 -7
  194. package/src/actions.ts +415 -0
  195. package/src/async.ts +78 -0
  196. package/src/compiled/async-resource.ts +113 -0
  197. package/src/compiled/core.ts +4041 -0
  198. package/src/compiled/types.ts +96 -0
  199. package/src/compiled/validation.ts +23 -0
  200. package/src/component-spread.ts +86 -0
  201. package/src/concurrent.ts +310 -0
  202. package/src/direct-dom.ts +365 -0
  203. package/src/dom/attributes.ts +55 -0
  204. package/src/dom/events.ts +93 -0
  205. package/src/dom/forms.ts +220 -0
  206. package/src/dom/intrinsic.ts +94 -0
  207. package/src/dom/namespace.ts +30 -0
  208. package/src/dom/namespaces.ts +14 -0
  209. package/src/dom/properties.ts +355 -0
  210. package/src/dom/style-properties.ts +46 -0
  211. package/src/dom/styles.ts +86 -0
  212. package/src/dom-forms.ts +23 -0
  213. package/src/dom-styles.ts +11 -0
  214. package/src/env.d.ts +6 -0
  215. package/src/framework-hydrate.ts +224 -0
  216. package/src/framework-protocol.ts +335 -0
  217. package/src/framework.ts +161 -0
  218. package/src/hydrate.ts +38 -0
  219. package/src/hydration-bridge.ts +196 -0
  220. package/src/hydration.ts +642 -0
  221. package/src/index.ts +92 -0
  222. package/src/indexed-list.ts +20 -0
  223. package/src/jsx-runtime.ts +55 -0
  224. package/src/keyed-list.ts +233 -0
  225. package/src/metadata.ts +212 -0
  226. package/src/nested-prop.ts +27 -0
  227. package/src/profiling.ts +43 -0
  228. package/src/protocol.ts +8 -0
  229. package/src/raw-html.ts +206 -0
  230. package/src/ref.ts +13 -0
  231. package/src/renderable-protocol.ts +63 -0
  232. package/src/renderable.ts +283 -0
  233. package/src/retained-ui.ts +19 -0
  234. package/src/root.ts +122 -0
  235. package/src/scheduler.ts +136 -0
  236. package/src/server-framework.ts +397 -0
  237. package/src/server.ts +1160 -0
  238. package/src/shared/promise.ts +28 -0
  239. package/src/source-mask.ts +83 -0
  240. package/src/spread.ts +131 -0
  241. package/src/state-slot.ts +76 -0
  242. package/src/testing.ts +27 -0
  243. package/dist/index.d.ts.map +0 -1
  244. package/dist/index.js.map +0 -1
@@ -0,0 +1,96 @@
1
+ import type { RenderableProtocol } from '../renderable-protocol.ts'
2
+ import type { SourceMask } from '../source-mask.ts'
3
+
4
+ export const BINDING = Symbol.for('vidact.v1.Binding')
5
+ export const STRUCTURAL = Symbol.for('vidact.v1.StructuralBinding')
6
+ export const CONTEXT = Symbol.for('vidact.v1.Context')
7
+ export const ASYNC_RESOURCE = Symbol.for('vidact.v1.AsyncResource')
8
+ export const SUSPENSION = Symbol.for('vidact.v1.Suspension')
9
+ export const COMPONENT_SPREAD_SOURCE = Symbol.for('vidact.v1.ComponentSpreadSource')
10
+
11
+ export type CompiledErrorHandler = (error: unknown) => void
12
+
13
+ export type ProfilerPhase = 'mount' | 'update' | 'nested-update'
14
+
15
+ export type ProfilerOnRender = (
16
+ id: string,
17
+ phase: ProfilerPhase,
18
+ actualDuration: number,
19
+ baseDuration: number,
20
+ startTime: number,
21
+ commitTime: number,
22
+ ) => void
23
+
24
+ export type AsyncResourceState<Value> = {
25
+ status: 'pending' | 'fulfilled' | 'rejected'
26
+ value: Value | undefined
27
+ reason: unknown
28
+ readonly listeners: Set<() => void>
29
+ readonly cancel: (() => void) | undefined
30
+ subscribers: number
31
+ }
32
+
33
+ export interface AsyncResource<Value> {
34
+ readonly [ASYNC_RESOURCE]: AsyncResourceState<Value>
35
+ }
36
+
37
+ export interface ResourceOptions {
38
+ readonly cancel?: () => void
39
+ }
40
+
41
+ export type Suspension = {
42
+ readonly [SUSPENSION]: true
43
+ readonly resource: AsyncResource<unknown>
44
+ }
45
+
46
+ export type LazyModule<Props extends Record<string, unknown>> = {
47
+ readonly default: (props: Props) => CompiledRenderValue
48
+ }
49
+
50
+ export type CompiledScope = readonly [
51
+ add: (reads: SourceMask, run: (active: SourceMask) => void, writes?: SourceMask) => () => void,
52
+ invalidate: (sources: SourceMask) => void,
53
+ batch: <T>(operation: () => T) => T,
54
+ dispose: () => void,
55
+ ]
56
+
57
+ export type CompiledBinding<T> = readonly [
58
+ brand: typeof BINDING,
59
+ evaluate: () => T,
60
+ scope: CompiledScope,
61
+ reads: SourceMask,
62
+ additionalScope: CompiledScope | undefined,
63
+ additionalReads: SourceMask | undefined,
64
+ ]
65
+
66
+ export type OwnedBlock = readonly [
67
+ brand: typeof STRUCTURAL,
68
+ mount: (parent: Node, before: Node | null) => void,
69
+ hydrationKind?: 'array' | 'slot' | 'transparent',
70
+ ]
71
+
72
+ export type StructuralBinding = OwnedBlock
73
+ export type CompiledComponentResult = OwnedBlock
74
+
75
+ export type CompiledRenderValue =
76
+ | Node
77
+ | string
78
+ | number
79
+ | bigint
80
+ | boolean
81
+ | null
82
+ | undefined
83
+ | CompiledBinding<unknown>
84
+ | StructuralBinding
85
+ | RenderableProtocol
86
+ | readonly CompiledRenderValue[]
87
+
88
+ export interface CompiledContext<T> {
89
+ (props: {
90
+ readonly children?: CompiledRenderValue | readonly CompiledRenderValue[]
91
+ readonly value: T | CompiledBinding<T>
92
+ }): StructuralBinding
93
+ Provider: CompiledContext<T>
94
+ displayName?: string
95
+ readonly [CONTEXT]: T
96
+ }
@@ -0,0 +1,23 @@
1
+ import { isRenderableProtocol } from '../renderable-protocol.ts'
2
+ import { isCompiledBinding, isStructuralBinding } from './core.ts'
3
+
4
+ export function hasInvalidChild(children: readonly unknown[]): boolean {
5
+ for (const child of children) {
6
+ if (isStructuralBinding(child) || isCompiledBinding(child) || isRenderableProtocol(child)) {
7
+ continue
8
+ }
9
+ if (Array.isArray(child)) {
10
+ if (hasInvalidChild(child)) return true
11
+ continue
12
+ }
13
+ const type = typeof child
14
+ if (
15
+ type === 'function' ||
16
+ type === 'symbol' ||
17
+ (type === 'object' && child !== null && !(child instanceof Node))
18
+ ) {
19
+ return true
20
+ }
21
+ }
22
+ return false
23
+ }
@@ -0,0 +1,86 @@
1
+ import { COMPONENT_SPREAD_SOURCE, binding, mountCompiledProp } from './compiled/core.ts'
2
+ import type { CompiledBinding } from './compiled/types.ts'
3
+ import { INTERNAL_COMPONENT_SPREAD_PROP } from './dom/intrinsic.ts'
4
+
5
+ type Props = Record<string, unknown>
6
+ type ComponentSpreadDirective = (props: Props) => Props
7
+ const DEV = typeof __VIDACT_DEV__ === 'undefined' || __VIDACT_DEV__
8
+
9
+ function readSpreadValue(value: unknown): Props {
10
+ if (value === null || value === undefined) return {}
11
+ if (typeof value !== 'object') {
12
+ throw new TypeError(
13
+ DEV ? 'reactive component spread value must be an object or nullish' : 'V106',
14
+ )
15
+ }
16
+ if (Object.hasOwn(value, 'key')) {
17
+ throw new TypeError(DEV ? 'reactive component spreads cannot supply key' : 'V106')
18
+ }
19
+ return value as Props
20
+ }
21
+
22
+ export function compiledComponentSpread(
23
+ input: CompiledBinding<Props>,
24
+ overriddenNames: readonly string[],
25
+ ): Record<PropertyKey, ComponentSpreadDirective> {
26
+ const overridden = new Set(overriddenNames)
27
+ const bindings = new Map<string, CompiledBinding<unknown>>()
28
+ const read = (): Props => readSpreadValue(input[1]())
29
+ const propBinding = (name: string): CompiledBinding<unknown> => {
30
+ let value = bindings.get(name)
31
+ if (value === undefined) {
32
+ value = binding(input[2], input[3], () => read()[name], input[4], input[5])
33
+ bindings.set(name, value)
34
+ }
35
+ return value
36
+ }
37
+
38
+ return {
39
+ [INTERNAL_COMPONENT_SPREAD_PROP]: (explicitProps) => {
40
+ mountCompiledProp(input, (value) => {
41
+ readSpreadValue(value)
42
+ })
43
+ return new Proxy(explicitProps, {
44
+ get(target, property, receiver) {
45
+ if (property === COMPONENT_SPREAD_SOURCE) return input
46
+ if (
47
+ typeof property !== 'string' ||
48
+ overridden.has(property) ||
49
+ Object.hasOwn(target, property)
50
+ ) {
51
+ return Reflect.get(target, property, receiver)
52
+ }
53
+ return propBinding(property)
54
+ },
55
+ getOwnPropertyDescriptor(target, property) {
56
+ const descriptor = Reflect.getOwnPropertyDescriptor(target, property)
57
+ if (
58
+ descriptor !== undefined ||
59
+ typeof property !== 'string' ||
60
+ overridden.has(property) ||
61
+ !Object.hasOwn(read(), property)
62
+ ) {
63
+ return descriptor
64
+ }
65
+ return { configurable: true, enumerable: true }
66
+ },
67
+ has(target, property) {
68
+ return (
69
+ Reflect.has(target, property) ||
70
+ (typeof property === 'string' &&
71
+ !overridden.has(property) &&
72
+ Object.hasOwn(read(), property))
73
+ )
74
+ },
75
+ ownKeys(target) {
76
+ return [
77
+ ...new Set([
78
+ ...Reflect.ownKeys(target),
79
+ ...Object.keys(read()).filter((name) => !overridden.has(name)),
80
+ ]),
81
+ ]
82
+ },
83
+ })
84
+ },
85
+ }
86
+ }
@@ -0,0 +1,310 @@
1
+ import { createCompiledState, runCompiledTransaction } from './compiled/core.ts'
2
+ import type { CompiledScope } from './compiled/types.ts'
3
+ import { flushScheduledTasks, scheduleDeferredTask, type CancelScheduledTask } from './scheduler.ts'
4
+ import type { SourceMask } from './source-mask.ts'
5
+ import {
6
+ installStateWriteInterceptor,
7
+ type DeferredStateWrite,
8
+ type StateSlot,
9
+ type StateUpdate,
10
+ } from './state-slot.ts'
11
+
12
+ const DEV = typeof __VIDACT_DEV__ === 'undefined' || __VIDACT_DEV__
13
+
14
+ type TransitionAction = () => void | PromiseLike<void>
15
+
16
+ type StagedSlot = {
17
+ readonly revision: number
18
+ readonly currentRevision: () => number
19
+ readonly commit: (update: StateUpdate<unknown>) => void
20
+ readonly updates: StateUpdate<unknown>[]
21
+ }
22
+
23
+ type TransitionWork = {
24
+ readonly lane: TransitionLane
25
+ readonly generation: number
26
+ readonly slots: Map<object, StagedSlot>
27
+ readonly settled: Set<() => void>
28
+ readonly finalizers: Set<() => void>
29
+ readonly aborters: Set<() => void>
30
+ cancelTask: CancelScheduledTask | undefined
31
+ awaiting: number
32
+ committed: boolean
33
+ canceled: boolean
34
+ finished: boolean
35
+ }
36
+
37
+ type TransitionLane = {
38
+ generation: number
39
+ current: TransitionWork | undefined
40
+ readonly pending: (value: boolean) => void
41
+ }
42
+
43
+ export interface CompiledTransitionSlot {
44
+ readonly get: () => boolean
45
+ readonly set: (action: TransitionAction) => void
46
+ }
47
+
48
+ let activeTransition: TransitionWork | undefined
49
+ let schedulerInstalled = false
50
+ const globalLane = createLane(() => {})
51
+
52
+ export function startTransition(action: TransitionAction): void {
53
+ ensureConcurrentScheduler()
54
+ startLaneTransition(globalLane, action)
55
+ }
56
+
57
+ export function flushSync<Result>(operation?: () => Result): Result | undefined {
58
+ ensureConcurrentScheduler()
59
+ const previous = activeTransition
60
+ activeTransition = undefined
61
+ try {
62
+ const result = operation?.()
63
+ flushScheduledTasks()
64
+ return result
65
+ } finally {
66
+ activeTransition = previous
67
+ }
68
+ }
69
+
70
+ export function createCompiledTransition(
71
+ scope: CompiledScope,
72
+ sourceMask: SourceMask,
73
+ ): CompiledTransitionSlot {
74
+ ensureConcurrentScheduler()
75
+ const pending = createCompiledState(scope, sourceMask, false)
76
+ const lane = createLane((value) => runUrgent(() => pending.replace(value)))
77
+ return {
78
+ get: pending.get,
79
+ set: (action) => startLaneTransition(lane, action),
80
+ }
81
+ }
82
+
83
+ export function createCompiledDeferred<Value>(
84
+ scope: CompiledScope,
85
+ reads: SourceMask,
86
+ writes: SourceMask,
87
+ evaluate: () => Value,
88
+ initialValue?: Value,
89
+ ): StateSlot<Value> {
90
+ ensureConcurrentScheduler()
91
+ const slot = createCompiledState(
92
+ scope,
93
+ writes,
94
+ arguments.length >= 5 ? initialValue! : evaluate(),
95
+ )
96
+ const lane = createLane(() => {})
97
+ const update = (): void => {
98
+ startLaneTransition(lane, () => slot.replace(evaluate()))
99
+ }
100
+ scope[0](reads, update)
101
+ if (arguments.length >= 5) update()
102
+ return slot
103
+ }
104
+
105
+ export function useTransition(): never {
106
+ throw new Error(DEV ? 'useTransition requires compiler lowering' : 'V032')
107
+ }
108
+
109
+ export function useDeferredValue<Value>(_value: Value, _initialValue?: Value): never {
110
+ throw new Error(DEV ? 'useDeferredValue requires compiler lowering' : 'V033')
111
+ }
112
+
113
+ /** @internal */
114
+ export function registerTransitionSettlement(settle: () => void): boolean {
115
+ if (activeTransition === undefined) return false
116
+ activeTransition.settled.add(settle)
117
+ return true
118
+ }
119
+
120
+ /** @internal */
121
+ export function registerTransitionFinalizer(finalize: () => void): boolean {
122
+ if (activeTransition === undefined) return false
123
+ activeTransition.finalizers.add(finalize)
124
+ return true
125
+ }
126
+
127
+ /** @internal */
128
+ export function registerTransitionAborter(abort: () => void): boolean {
129
+ if (activeTransition === undefined) return false
130
+ activeTransition.aborters.add(abort)
131
+ return true
132
+ }
133
+
134
+ /** @internal */
135
+ export function runUrgentUpdate<Result>(operation: () => Result): Result {
136
+ return runUrgent(operation)
137
+ }
138
+
139
+ /** @internal */
140
+ export function startIndependentTransition(action: TransitionAction): void {
141
+ ensureConcurrentScheduler()
142
+ const previous = activeTransition
143
+ activeTransition = undefined
144
+ try {
145
+ startLaneTransition(
146
+ createLane(() => {}),
147
+ action,
148
+ )
149
+ } finally {
150
+ activeTransition = previous
151
+ }
152
+ }
153
+
154
+ function createLane(pending: (value: boolean) => void): TransitionLane {
155
+ return { generation: 0, current: undefined, pending }
156
+ }
157
+
158
+ function ensureConcurrentScheduler(): void {
159
+ if (schedulerInstalled) return
160
+ schedulerInstalled = true
161
+ installStateWriteInterceptor(stageStateWrite)
162
+ }
163
+
164
+ function startLaneTransition(lane: TransitionLane, action: TransitionAction): void {
165
+ if (activeTransition !== undefined) {
166
+ lane.pending(true)
167
+ activeTransition.settled.add(() => lane.pending(false))
168
+ runTransitionAction(activeTransition, action)
169
+ return
170
+ }
171
+
172
+ cancelWork(lane.current, true)
173
+ lane.generation += 1
174
+ lane.pending(true)
175
+ const work: TransitionWork = {
176
+ lane,
177
+ generation: lane.generation,
178
+ slots: new Map(),
179
+ settled: new Set(),
180
+ finalizers: new Set(),
181
+ aborters: new Set(),
182
+ cancelTask: undefined,
183
+ awaiting: 0,
184
+ committed: false,
185
+ canceled: false,
186
+ finished: false,
187
+ }
188
+ lane.current = work
189
+ const previous = activeTransition
190
+ activeTransition = work
191
+ try {
192
+ runTransitionAction(work, action)
193
+ } catch (error) {
194
+ cancelWork(work)
195
+ throw error
196
+ } finally {
197
+ activeTransition = previous
198
+ }
199
+ work.cancelTask = scheduleDeferredTask(() => commitWork(work))
200
+ }
201
+
202
+ function runTransitionAction(work: TransitionWork, action: TransitionAction): void {
203
+ const result = action()
204
+ if (!isPromiseLike(result)) return
205
+ work.awaiting += 1
206
+ void Promise.resolve(result).then(
207
+ () => {
208
+ work.awaiting -= 1
209
+ finishWork(work)
210
+ },
211
+ (error: unknown) => {
212
+ work.awaiting -= 1
213
+ cancelWork(work)
214
+ queueMicrotask(() => {
215
+ throw error
216
+ })
217
+ },
218
+ )
219
+ }
220
+
221
+ function stageStateWrite<Value>(write: DeferredStateWrite<Value>): boolean {
222
+ const work = activeTransition
223
+ if (work === undefined || work.canceled) return false
224
+ let staged = work.slots.get(write.slot)
225
+ if (staged === undefined) {
226
+ staged = {
227
+ revision: write.revision,
228
+ currentRevision: write.currentRevision,
229
+ commit: write.commit as (update: StateUpdate<unknown>) => void,
230
+ updates: [],
231
+ }
232
+ work.slots.set(write.slot, staged)
233
+ }
234
+ staged.updates.push(write.update as StateUpdate<unknown>)
235
+ return true
236
+ }
237
+
238
+ function commitWork(work: TransitionWork): void {
239
+ work.cancelTask = undefined
240
+ if (
241
+ work.canceled ||
242
+ work.lane.current !== work ||
243
+ work.lane.generation !== work.generation ||
244
+ [...work.slots.values()].some((slot) => slot.currentRevision() !== slot.revision)
245
+ ) {
246
+ cancelWork(work)
247
+ return
248
+ }
249
+ const previous = activeTransition
250
+ activeTransition = undefined
251
+ try {
252
+ runCompiledTransaction(() => {
253
+ for (const slot of work.slots.values()) {
254
+ for (const update of slot.updates) slot.commit(update)
255
+ }
256
+ })
257
+ for (const finalize of work.finalizers) finalize()
258
+ work.finalizers.clear()
259
+ work.aborters.clear()
260
+ work.committed = true
261
+ } catch (error) {
262
+ cancelWork(work)
263
+ throw error
264
+ } finally {
265
+ activeTransition = previous
266
+ finishWork(work)
267
+ }
268
+ }
269
+
270
+ function cancelWork(work: TransitionWork | undefined, preserveLanePending = false): void {
271
+ if (work === undefined || work.finished) return
272
+ work.canceled = true
273
+ work.cancelTask?.()
274
+ work.cancelTask = undefined
275
+ work.finalizers.clear()
276
+ for (const abort of work.aborters) abort()
277
+ work.aborters.clear()
278
+ work.committed = true
279
+ work.awaiting = 0
280
+ if (preserveLanePending && work.lane.current === work) work.lane.current = undefined
281
+ finishWork(work)
282
+ }
283
+
284
+ function finishWork(work: TransitionWork): void {
285
+ if (work.finished || !work.committed || work.awaiting > 0) return
286
+ work.finished = true
287
+ if (work.lane.current === work) {
288
+ work.lane.current = undefined
289
+ work.lane.pending(false)
290
+ }
291
+ for (const settle of work.settled) settle()
292
+ work.settled.clear()
293
+ }
294
+
295
+ function runUrgent<Result>(operation: () => Result): Result {
296
+ const previous = activeTransition
297
+ activeTransition = undefined
298
+ try {
299
+ return operation()
300
+ } finally {
301
+ activeTransition = previous
302
+ }
303
+ }
304
+
305
+ function isPromiseLike(value: unknown): value is PromiseLike<void> {
306
+ return (
307
+ ((typeof value === 'object' && value !== null) || typeof value === 'function') &&
308
+ typeof (value as PromiseLike<void>).then === 'function'
309
+ )
310
+ }