@reactive-vscode/reactivity 0.2.0-beta.1 → 0.2.0-beta.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@reactive-vscode/reactivity",
3
3
  "type": "module",
4
- "version": "0.2.0-beta.1",
4
+ "version": "0.2.0-beta.2",
5
5
  "description": "Full Vue Reactivity API without DOM",
6
6
  "author": "_Kerman <kermanx@qq.com>",
7
7
  "license": "MIT",
@@ -18,25 +18,25 @@
18
18
  "sideEffects": false,
19
19
  "exports": {
20
20
  ".": {
21
- "types": "./src/index.ts",
22
- "import": "./src/index.ts"
21
+ "types": "./dist/index.d.ts",
22
+ "import": "./dist/index.js"
23
23
  }
24
24
  },
25
- "main": "./src/index.ts",
26
- "types": "./src/index.ts",
25
+ "main": "./dist/index.js",
26
+ "types": "./dist/index.d.ts",
27
27
  "files": [
28
28
  "README.md",
29
- "shim.d.ts",
30
- "src",
31
- "tsconfig.json"
29
+ "dist"
32
30
  ],
33
- "dependencies": {},
34
31
  "devDependencies": {
35
32
  "@vue/reactivity": "^3.4.27",
36
33
  "@vue/shared": "^3.4.27",
37
- "typescript": "^5.4.5"
34
+ "typescript": "^5.4.5",
35
+ "vite": "^5.2.12",
36
+ "vite-plugin-dts": "^3.9.1"
38
37
  },
39
38
  "scripts": {
40
- "typecheck": "tsc --noEmit"
39
+ "typecheck": "tsc --noEmit",
40
+ "build": "vite build"
41
41
  }
42
42
  }
package/shim.d.ts DELETED
@@ -1,4 +0,0 @@
1
- export {}
2
- declare global {
3
- const __DEV__: boolean
4
- }
package/src/apiWatch.ts DELETED
@@ -1,415 +0,0 @@
1
- import {
2
- type ComputedRef,
3
- type DebuggerOptions,
4
- type EffectScheduler,
5
- ReactiveEffect,
6
- ReactiveFlags,
7
- type Ref,
8
- getCurrentScope,
9
- isReactive,
10
- isRef,
11
- isShallow,
12
- } from '@vue/reactivity'
13
- import { type SchedulerJob, queueJob } from './scheduler'
14
- import {
15
- EMPTY_OBJ,
16
- NOOP,
17
- extend,
18
- hasChanged,
19
- isArray,
20
- isFunction,
21
- isMap,
22
- isObject,
23
- isPlainObject,
24
- isSet,
25
- remove,
26
- } from '@vue/shared'
27
- import {
28
- ErrorCodes,
29
- callWithAsyncErrorHandling,
30
- callWithErrorHandling,
31
- } from './errorHandling'
32
- import { warn } from './warning'
33
-
34
- export type WatchEffect = (onCleanup: OnCleanup) => void
35
-
36
- export type WatchSource<T = any> = Ref<T> | ComputedRef<T> | (() => T)
37
-
38
- export type WatchCallback<V = any, OV = any> = (
39
- value: V,
40
- oldValue: OV,
41
- onCleanup: OnCleanup,
42
- ) => any
43
-
44
- type MapSources<T, Immediate> = {
45
- [K in keyof T]: T[K] extends WatchSource<infer V>
46
- ? Immediate extends true
47
- ? V | undefined
48
- : V
49
- : T[K] extends object
50
- ? Immediate extends true
51
- ? T[K] | undefined
52
- : T[K]
53
- : never
54
- }
55
-
56
- export type OnCleanup = (cleanupFn: () => void) => void
57
-
58
- export interface WatchOptionsBase extends DebuggerOptions {
59
- flush?: 'pre' | 'post' | 'sync'
60
- }
61
-
62
- export interface WatchOptions<Immediate = boolean> extends WatchOptionsBase {
63
- immediate?: Immediate
64
- deep?: boolean
65
- once?: boolean
66
- }
67
-
68
- export type WatchStopHandle = () => void
69
-
70
- // Simple effect.
71
- export function watchEffect(
72
- effect: WatchEffect,
73
- options?: WatchOptionsBase,
74
- ): WatchStopHandle {
75
- return doWatch(effect, null, options)
76
- }
77
-
78
- export function watchPostEffect(
79
- effect: WatchEffect,
80
- options?: DebuggerOptions,
81
- ) {
82
- return doWatch(
83
- effect,
84
- null,
85
- __DEV__ ? extend({}, options as any, { flush: 'post' }) : { flush: 'post' },
86
- )
87
- }
88
-
89
- export function watchSyncEffect(
90
- effect: WatchEffect,
91
- options?: DebuggerOptions,
92
- ) {
93
- return doWatch(
94
- effect,
95
- null,
96
- __DEV__ ? extend({}, options as any, { flush: 'sync' }) : { flush: 'sync' },
97
- )
98
- }
99
-
100
- // initial value for watchers to trigger on undefined initial values
101
- const INITIAL_WATCHER_VALUE = {}
102
-
103
- type MultiWatchSources = (WatchSource<unknown> | object)[]
104
-
105
- // overload: single source + cb
106
- export function watch<T, Immediate extends Readonly<boolean> = false>(
107
- source: WatchSource<T>,
108
- cb: WatchCallback<T, Immediate extends true ? T | undefined : T>,
109
- options?: WatchOptions<Immediate>,
110
- ): WatchStopHandle
111
-
112
- // overload: array of multiple sources + cb
113
- export function watch<
114
- T extends MultiWatchSources,
115
- Immediate extends Readonly<boolean> = false,
116
- >(
117
- sources: [...T],
118
- cb: WatchCallback<MapSources<T, false>, MapSources<T, Immediate>>,
119
- options?: WatchOptions<Immediate>,
120
- ): WatchStopHandle
121
-
122
- // overload: multiple sources w/ `as const`
123
- // watch([foo, bar] as const, () => {})
124
- // somehow [...T] breaks when the type is readonly
125
- export function watch<
126
- T extends Readonly<MultiWatchSources>,
127
- Immediate extends Readonly<boolean> = false,
128
- >(
129
- source: T,
130
- cb: WatchCallback<MapSources<T, false>, MapSources<T, Immediate>>,
131
- options?: WatchOptions<Immediate>,
132
- ): WatchStopHandle
133
-
134
- // overload: watching reactive object w/ cb
135
- export function watch<
136
- T extends object,
137
- Immediate extends Readonly<boolean> = false,
138
- >(
139
- source: T,
140
- cb: WatchCallback<T, Immediate extends true ? T | undefined : T>,
141
- options?: WatchOptions<Immediate>,
142
- ): WatchStopHandle
143
-
144
- // implementation
145
- export function watch<T = any, Immediate extends Readonly<boolean> = false>(
146
- source: T | WatchSource<T>,
147
- cb: any,
148
- options?: WatchOptions<Immediate>,
149
- ): WatchStopHandle {
150
- if (__DEV__ && !isFunction(cb)) {
151
- warn(
152
- `\`watch(fn, options?)\` signature has been moved to a separate API. ` +
153
- `Use \`watchEffect(fn, options?)\` instead. \`watch\` now only ` +
154
- `supports \`watch(source, cb, options?) signature.`,
155
- )
156
- }
157
- return doWatch(source as any, cb, options)
158
- }
159
-
160
- function doWatch(
161
- source: WatchSource | WatchSource[] | WatchEffect | object,
162
- cb: WatchCallback | null,
163
- {
164
- immediate,
165
- deep,
166
- flush,
167
- once,
168
- onTrack,
169
- onTrigger,
170
- }: WatchOptions = EMPTY_OBJ,
171
- ): WatchStopHandle {
172
- if (cb && once) {
173
- const _cb = cb
174
- cb = (...args) => {
175
- _cb(...args)
176
- unwatch()
177
- }
178
- }
179
-
180
- // TODO remove in 3.5
181
- if (__DEV__ && deep !== void 0 && typeof deep === 'number') {
182
- warn(
183
- `watch() "deep" option with number value will be used as watch depth in future versions. ` +
184
- `Please use a boolean instead to avoid potential breakage.`,
185
- )
186
- }
187
-
188
- if (__DEV__ && !cb) {
189
- if (immediate !== undefined) {
190
- warn(
191
- `watch() "immediate" option is only respected when using the ` +
192
- `watch(source, callback, options?) signature.`,
193
- )
194
- }
195
- if (deep !== undefined) {
196
- warn(
197
- `watch() "deep" option is only respected when using the ` +
198
- `watch(source, callback, options?) signature.`,
199
- )
200
- }
201
- if (once !== undefined) {
202
- warn(
203
- `watch() "once" option is only respected when using the ` +
204
- `watch(source, callback, options?) signature.`,
205
- )
206
- }
207
- }
208
-
209
- const warnInvalidSource = (s: unknown) => {
210
- warn(
211
- `Invalid watch source: `,
212
- s,
213
- `A watch source can only be a getter/effect function, a ref, ` +
214
- `a reactive object, or an array of these types.`,
215
- )
216
- }
217
-
218
- const instance = null
219
- const reactiveGetter = (source: object) =>
220
- deep === true
221
- ? source // traverse will happen in wrapped getter below
222
- : // for deep: false, only traverse root-level properties
223
- traverse(source, deep === false ? 1 : undefined)
224
-
225
- let getter: () => any
226
- let forceTrigger = false
227
- let isMultiSource = false
228
-
229
- if (isRef(source)) {
230
- getter = () => source.value
231
- forceTrigger = isShallow(source)
232
- } else if (isReactive(source)) {
233
- getter = () => reactiveGetter(source)
234
- forceTrigger = true
235
- } else if (isArray(source)) {
236
- isMultiSource = true
237
- forceTrigger = source.some(s => isReactive(s) || isShallow(s))
238
- getter = () =>
239
- source.map(s => {
240
- if (isRef(s)) {
241
- return s.value
242
- } else if (isReactive(s)) {
243
- return reactiveGetter(s)
244
- } else if (isFunction(s)) {
245
- return callWithErrorHandling(s, instance, ErrorCodes.WATCH_GETTER)
246
- } else {
247
- __DEV__ && warnInvalidSource(s)
248
- }
249
- })
250
- } else if (isFunction(source)) {
251
- if (cb) {
252
- // getter with cb
253
- getter = () =>
254
- callWithErrorHandling(source, instance, ErrorCodes.WATCH_GETTER)
255
- } else {
256
- // no cb -> simple effect
257
- getter = () => {
258
- if (cleanup) {
259
- cleanup()
260
- }
261
- return callWithAsyncErrorHandling(
262
- source,
263
- instance,
264
- ErrorCodes.WATCH_CALLBACK,
265
- [onCleanup],
266
- )
267
- }
268
- }
269
- } else {
270
- getter = NOOP
271
- __DEV__ && warnInvalidSource(source)
272
- }
273
-
274
- if (cb && deep) {
275
- const baseGetter = getter
276
- getter = () => traverse(baseGetter())
277
- }
278
-
279
- let cleanup: (() => void) | undefined
280
- let onCleanup: OnCleanup = (fn: () => void) => {
281
- cleanup = effect.onStop = () => {
282
- callWithErrorHandling(fn, instance, ErrorCodes.WATCH_CLEANUP)
283
- cleanup = effect.onStop = undefined
284
- }
285
- }
286
-
287
- let oldValue: any = isMultiSource
288
- ? new Array((source as []).length).fill(INITIAL_WATCHER_VALUE)
289
- : INITIAL_WATCHER_VALUE
290
- const job: SchedulerJob = () => {
291
- if (!effect.active || !effect.dirty) {
292
- return
293
- }
294
- if (cb) {
295
- // watch(source, cb)
296
- const newValue = effect.run()
297
- if (
298
- deep ||
299
- forceTrigger ||
300
- (isMultiSource
301
- ? (newValue as any[]).some((v, i) => hasChanged(v, oldValue[i]))
302
- : hasChanged(newValue, oldValue))
303
- ) {
304
- // cleanup before running cb again
305
- if (cleanup) {
306
- cleanup()
307
- }
308
- callWithAsyncErrorHandling(cb, instance, ErrorCodes.WATCH_CALLBACK, [
309
- newValue,
310
- // pass undefined as the old value when it's changed for the first time
311
- oldValue === INITIAL_WATCHER_VALUE
312
- ? undefined
313
- : isMultiSource && oldValue[0] === INITIAL_WATCHER_VALUE
314
- ? []
315
- : oldValue,
316
- onCleanup,
317
- ])
318
- oldValue = newValue
319
- }
320
- } else {
321
- // watchEffect
322
- effect.run()
323
- }
324
- }
325
-
326
- // important: mark the job as a watcher callback so that scheduler knows
327
- // it is allowed to self-trigger (#1727)
328
- job.allowRecurse = !!cb
329
-
330
- let scheduler: EffectScheduler
331
- if (flush === 'sync') {
332
- scheduler = job as any // the scheduler function gets called directly
333
- } else {
334
- // default: 'pre'
335
- job.pre = true
336
- scheduler = () => queueJob(job)
337
- }
338
-
339
- const effect = new ReactiveEffect(getter, NOOP, scheduler)
340
-
341
- const scope = getCurrentScope()
342
- const unwatch = () => {
343
- effect.stop()
344
- if (scope) {
345
- // @ts-ignore for internal use
346
- remove(scope.effects, effect)
347
- }
348
- }
349
-
350
- if (__DEV__) {
351
- effect.onTrack = onTrack
352
- effect.onTrigger = onTrigger
353
- }
354
-
355
- // initial run
356
- if (cb) {
357
- if (immediate) {
358
- job()
359
- } else {
360
- oldValue = effect.run()
361
- }
362
- } else {
363
- effect.run()
364
- }
365
- return unwatch
366
- }
367
-
368
- export function createPathGetter(ctx: any, path: string) {
369
- const segments = path.split('.')
370
- return () => {
371
- let cur = ctx
372
- for (let i = 0; i < segments.length && cur; i++) {
373
- cur = cur[segments[i]]
374
- }
375
- return cur
376
- }
377
- }
378
-
379
- export function traverse(
380
- value: unknown,
381
- depth = Infinity,
382
- seen?: Set<unknown>,
383
- ) {
384
- if (depth <= 0 || !isObject(value) || (value as any)[ReactiveFlags.SKIP]) {
385
- return value
386
- }
387
-
388
- seen = seen || new Set()
389
- if (seen.has(value)) {
390
- return value
391
- }
392
- seen.add(value)
393
- depth--
394
- if (isRef(value)) {
395
- traverse(value.value, depth, seen)
396
- } else if (isArray(value)) {
397
- for (let i = 0; i < value.length; i++) {
398
- traverse(value[i], depth, seen)
399
- }
400
- } else if (isSet(value) || isMap(value)) {
401
- value.forEach((v: any) => {
402
- traverse(v, depth, seen)
403
- })
404
- } else if (isPlainObject(value)) {
405
- for (const key in value) {
406
- traverse(value[key], depth, seen)
407
- }
408
- for (const key of Object.getOwnPropertySymbols(value)) {
409
- if (Object.prototype.propertyIsEnumerable.call(value, key)) {
410
- traverse(value[key as any], depth, seen)
411
- }
412
- }
413
- }
414
- return value
415
- }
package/src/enums.ts DELETED
@@ -1,4 +0,0 @@
1
- export enum LifecycleHooks {
2
- ACTIVATED = 'a',
3
- DEACTIVATED = 'da',
4
- }
@@ -1,120 +0,0 @@
1
- import { warn } from './warning'
2
- import { isArray, isFunction, isPromise } from '@vue/shared'
3
- import { LifecycleHooks } from './enums'
4
-
5
- // contexts where user provided function may be executed, in addition to
6
- // lifecycle hooks.
7
- export enum ErrorCodes {
8
- SETUP_FUNCTION,
9
- RENDER_FUNCTION,
10
- WATCH_GETTER,
11
- WATCH_CALLBACK,
12
- WATCH_CLEANUP,
13
- NATIVE_EVENT_HANDLER,
14
- COMPONENT_EVENT_HANDLER,
15
- VNODE_HOOK,
16
- DIRECTIVE_HOOK,
17
- TRANSITION_HOOK,
18
- APP_ERROR_HANDLER,
19
- APP_WARN_HANDLER,
20
- FUNCTION_REF,
21
- ASYNC_COMPONENT_LOADER,
22
- SCHEDULER,
23
- }
24
-
25
- export const ErrorTypeStrings: Record<LifecycleHooks | ErrorCodes, string> = {
26
- [LifecycleHooks.ACTIVATED]: 'activated hook',
27
- [LifecycleHooks.DEACTIVATED]: 'deactivated hook',
28
- [ErrorCodes.SETUP_FUNCTION]: 'setup function',
29
- [ErrorCodes.RENDER_FUNCTION]: 'render function',
30
- [ErrorCodes.WATCH_GETTER]: 'watcher getter',
31
- [ErrorCodes.WATCH_CALLBACK]: 'watcher callback',
32
- [ErrorCodes.WATCH_CLEANUP]: 'watcher cleanup function',
33
- [ErrorCodes.NATIVE_EVENT_HANDLER]: 'native event handler',
34
- [ErrorCodes.COMPONENT_EVENT_HANDLER]: 'component event handler',
35
- [ErrorCodes.VNODE_HOOK]: 'vnode hook',
36
- [ErrorCodes.DIRECTIVE_HOOK]: 'directive hook',
37
- [ErrorCodes.TRANSITION_HOOK]: 'transition hook',
38
- [ErrorCodes.APP_ERROR_HANDLER]: 'app errorHandler',
39
- [ErrorCodes.APP_WARN_HANDLER]: 'app warnHandler',
40
- [ErrorCodes.FUNCTION_REF]: 'ref function',
41
- [ErrorCodes.ASYNC_COMPONENT_LOADER]: 'async component loader',
42
- [ErrorCodes.SCHEDULER]:
43
- 'scheduler flush. This is likely a Vue internals bug. ' +
44
- 'Please open an issue at https://github.com/vuejs/core .',
45
- }
46
-
47
- export type ErrorTypes = LifecycleHooks | ErrorCodes
48
-
49
- export function callWithErrorHandling(
50
- fn: Function,
51
- instance: null,
52
- type: ErrorTypes,
53
- args?: unknown[],
54
- ) {
55
- try {
56
- return args ? fn(...args) : fn()
57
- } catch (err) {
58
- handleError(err, instance, type)
59
- }
60
- }
61
-
62
- export function callWithAsyncErrorHandling(
63
- fn: Function | Function[],
64
- instance: null,
65
- type: ErrorTypes,
66
- args?: unknown[],
67
- ): any {
68
- if (isFunction(fn)) {
69
- const res = callWithErrorHandling(fn, instance, type, args)
70
- if (res && isPromise(res)) {
71
- res.catch(err => {
72
- handleError(err, instance, type)
73
- })
74
- }
75
- return res
76
- }
77
-
78
- if (isArray(fn)) {
79
- const values = []
80
- for (let i = 0; i < fn.length; i++) {
81
- values.push(callWithAsyncErrorHandling(fn[i], instance, type, args))
82
- }
83
- return values
84
- } else if (__DEV__) {
85
- warn(
86
- `Invalid value type passed to callWithAsyncErrorHandling(): ${typeof fn}`,
87
- )
88
- }
89
- }
90
-
91
- export function handleError(
92
- err: unknown,
93
- instance: null,
94
- type: ErrorTypes,
95
- throwInDev = true,
96
- ) {
97
- const contextVNode = null
98
- logError(err, type, contextVNode, throwInDev)
99
- }
100
-
101
- function logError(
102
- err: unknown,
103
- type: ErrorTypes,
104
- contextVNode: null,
105
- throwInDev = true,
106
- ) {
107
- if (__DEV__) {
108
- const info = ErrorTypeStrings[type]
109
- warn(`Unhandled error${info ? ` during execution of ${info}` : ``}`)
110
- // crash in dev by default so it's more noticeable
111
- if (throwInDev) {
112
- throw err
113
- } else {
114
- console.error(err)
115
- }
116
- } else {
117
- // recover in prod to reduce the impact on end-user
118
- console.error(err)
119
- }
120
- }
package/src/index.ts DELETED
@@ -1,5 +0,0 @@
1
- export { nextTick } from './scheduler'
2
- export type { WatchEffect, WatchSource, WatchCallback, WatchOptionsBase, WatchOptions, WatchStopHandle } from './apiWatch'
3
- export { watchEffect, watchSyncEffect, watch } from './apiWatch'
4
-
5
- export * from '@vue/reactivity'