@crab-dev/wake 0.1.20 → 0.1.22

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/index.cjs CHANGED
@@ -2,6 +2,10 @@
2
2
 
3
3
  const { EventEmitter } = require('node:events')
4
4
  const { loadNative } = require('./loader.cjs')
5
+ const {
6
+ registerTestContext,
7
+ setTestContextFatalError,
8
+ } = require('./test-context-internal.cjs')
5
9
  const {
6
10
  WakeError,
7
11
  fromNativeError,
@@ -25,6 +29,196 @@ async function bundle(options) {
25
29
  return invoke(native.bundle(JSON.stringify(value), signal))
26
30
  }
27
31
 
32
+ function splitTestOptions(options) {
33
+ try {
34
+ return splitOptions(options)
35
+ } catch (error) {
36
+ if (error instanceof WakeError && error.code === 'WAKE_CONFIG') {
37
+ throw new WakeError('WAKE_TEST_CONFIG', error.message, { cause: error })
38
+ }
39
+ throw error
40
+ }
41
+ }
42
+
43
+ async function runTests(options) {
44
+ const [value, signal] = splitTestOptions(options)
45
+ return invoke(native.runTests(
46
+ JSON.stringify(value),
47
+ signal,
48
+ native.__wakeTestHostPath,
49
+ ))
50
+ }
51
+
52
+ class TestContext extends EventEmitter {
53
+ #native
54
+ #closed = false
55
+ #eventPoll
56
+
57
+ constructor(handle) {
58
+ super()
59
+ this.#native = handle
60
+ registerTestContext(this, handle)
61
+ }
62
+
63
+ get closed() {
64
+ return this.#closed || this.#native.closed
65
+ }
66
+
67
+ get watching() {
68
+ return Boolean(this.#native.watching)
69
+ }
70
+
71
+ async run() {
72
+ if (this.closed) throw new WakeError('WAKE_TEST_CONTEXT', 'TestContext has already been closed')
73
+ try {
74
+ const result = await invoke(this.#native.run())
75
+ this.#flushEvents()
76
+ return result
77
+ } catch (error) {
78
+ this.#flushEvents()
79
+ throw error
80
+ }
81
+ }
82
+
83
+ startWatch() {
84
+ if (this.closed) throw new WakeError('WAKE_TEST_CONTEXT', 'TestContext has already been closed')
85
+ try {
86
+ this.#native.startWatch()
87
+ this.#flushEvents()
88
+ this.#startEventPoll()
89
+ return this
90
+ } catch (error) {
91
+ throw fromNativeError(error)
92
+ }
93
+ }
94
+
95
+ stopWatch() {
96
+ if (this.closed) return this
97
+ try {
98
+ this.#native.stopWatch()
99
+ this.#flushEvents()
100
+ this.#stopEventPoll()
101
+ return this
102
+ } catch (error) {
103
+ throw fromNativeError(error)
104
+ }
105
+ }
106
+
107
+ async close() {
108
+ if (this.#closed) return
109
+ this.#closed = true
110
+ this.#stopEventPoll()
111
+ try {
112
+ await invoke(this.#native.close())
113
+ } finally {
114
+ this.#flushEvents()
115
+ }
116
+ }
117
+
118
+ async [Symbol.asyncDispose]() {
119
+ await this.close()
120
+ }
121
+
122
+ #flushEvents() {
123
+ this.#dispatchEvents(this.#readEvents())
124
+ }
125
+
126
+ #readEvents() {
127
+ let events
128
+ try {
129
+ events = JSON.parse(this.#native.eventsJson())
130
+ } catch (cause) {
131
+ const detail = cause instanceof Error ? cause.message : String(cause)
132
+ throw new WakeError(
133
+ 'WAKE_TEST_HOST',
134
+ `Wake returned an invalid test event stream: ${detail}`,
135
+ { cause },
136
+ )
137
+ }
138
+ if (!Array.isArray(events)) {
139
+ throw new WakeError('WAKE_TEST_HOST', 'Wake returned a non-array test event stream')
140
+ }
141
+ return events
142
+ }
143
+
144
+ #dispatchEvents(events) {
145
+ for (const event of events) {
146
+ switch (event.type) {
147
+ case 'runStart':
148
+ this.emit('runStart', { runId: event.runId, watching: event.watching })
149
+ break
150
+ case 'testCaseResult':
151
+ this.emit('testCaseResult', {
152
+ runId: event.runId,
153
+ suiteId: event.suiteId,
154
+ result: event.result,
155
+ })
156
+ break
157
+ case 'suiteResult':
158
+ this.emit('suiteResult', {
159
+ runId: event.runId,
160
+ result: event.result,
161
+ })
162
+ break
163
+ case 'diagnostic':
164
+ this.emit('diagnostic', event.diagnostic)
165
+ break
166
+ case 'runComplete':
167
+ this.emit('runComplete', event.result)
168
+ break
169
+ case 'closed':
170
+ this.emit('closed')
171
+ break
172
+ default:
173
+ throw new WakeError('WAKE_TEST_HOST', `Unknown test-host event: ${String(event.type)}`)
174
+ }
175
+ }
176
+ }
177
+
178
+ #startEventPoll() {
179
+ if (this.#eventPoll) return
180
+ this.#eventPoll = setInterval(() => {
181
+ let events
182
+ try {
183
+ events = this.#readEvents()
184
+ } catch (error) {
185
+ this.#stopEventPoll()
186
+ const fatalError = error instanceof WakeError
187
+ ? error
188
+ : new WakeError('WAKE_TEST_HOST', error instanceof Error ? error.message : String(error), {
189
+ cause: error,
190
+ })
191
+ setTestContextFatalError(this, fatalError)
192
+ // Host terminals are drained as ordered native events before this error becomes visible;
193
+ // closing then supplies the final public `closed` event without fabricating a duplicate
194
+ // JavaScript diagnostic.
195
+ void this.close().catch(() => {})
196
+ return
197
+ }
198
+ // User listeners execute outside the native/protocol error boundary. Their exceptions are
199
+ // ordinary EventEmitter failures and must never be relabeled as WAKE_TEST_HOST.
200
+ this.#dispatchEvents(events)
201
+ }, 25)
202
+ }
203
+
204
+ #stopEventPoll() {
205
+ if (!this.#eventPoll) return
206
+ clearInterval(this.#eventPoll)
207
+ this.#eventPoll = undefined
208
+ }
209
+ }
210
+
211
+ async function createTestContext(options) {
212
+ const [value] = splitTestOptions(options)
213
+ try {
214
+ return new TestContext(
215
+ native.createTestContext(JSON.stringify(value), native.__wakeTestHostPath),
216
+ )
217
+ } catch (error) {
218
+ throw fromNativeError(error)
219
+ }
220
+ }
221
+
28
222
  async function buildLibrary(options) {
29
223
  const [value, signal] = splitOptions(options)
30
224
  return invoke(native.buildLibrary(JSON.stringify(value), signal))
@@ -123,6 +317,8 @@ class DevServer extends EventEmitter {
123
317
  this.emit('rebuildStart', event)
124
318
  } else if (event.type === 'rebuilt') {
125
319
  this.emit('rebuilt', event)
320
+ } else if (event.type === 'workspaceState') {
321
+ this.emit('workspaceState', event)
126
322
  } else if (event.type === 'diagnostic') {
127
323
  this.emit('diagnostic', event.diagnostic)
128
324
  } else if (event.type === 'closed' && !this.#closed) {
@@ -206,14 +402,17 @@ function startDocsDevServer(options) {
206
402
  module.exports = {
207
403
  BuildContext,
208
404
  DevServer,
405
+ TestContext,
209
406
  WakeError,
210
407
  build,
211
408
  buildLibrary,
212
409
  buildDocs,
213
410
  bundle,
411
+ runTests,
214
412
  generateCssToken,
215
413
  generateDocgen,
216
414
  createBuildContext,
415
+ createTestContext,
217
416
  startDevServer,
218
417
  startDocsDevServer,
219
418
  version,
package/index.d.ts CHANGED
@@ -20,6 +20,23 @@ export type WakeErrorCode =
20
20
  | 'WAKE_LIBRARY_BUILD'
21
21
  | 'WAKE_LIBRARY_TYPE'
22
22
  | 'WAKE_LIBRARY_OUTPUT'
23
+ | 'WAKE_TEST_CONFIG'
24
+ | 'WAKE_TEST_DISCOVERY'
25
+ | 'WAKE_TEST_RUNTIME'
26
+ | 'WAKE_TEST_TIMEOUT'
27
+ | 'WAKE_TEST_SNAPSHOT'
28
+ | 'WAKE_TEST_COVERAGE'
29
+ | 'WAKE_TEST_HOST'
30
+ | 'WAKE_TEST_UNSUPPORTED'
31
+ | 'WAKE_TEST_CONTEXT'
32
+ | 'WAKE_TEST_DOM'
33
+ | 'WAKE_TEST_BROWSER'
34
+ | 'WAKE_TEST_REACT_VERSION'
35
+ | 'WAKE_TEST_NETWORK'
36
+ | 'WAKE_TEST_LEAK'
37
+ | 'WAKE_TEST_BUSY'
38
+ | 'WAKE_TEST_UNKNOWN_RUN'
39
+ | 'WAKE_TEST_UNKNOWN_WATCH'
23
40
 
24
41
  export interface DiagnosticLocation {
25
42
  /** One-based source line. */
@@ -66,6 +83,238 @@ export interface BuildOptions extends ProjectOptions {
66
83
  sourceMap?: boolean
67
84
  }
68
85
 
86
+ export type TestEnvironment = 'auto' | 'dom' | 'browser'
87
+ export type TestReporter = 'pretty' | 'json' | 'junit'
88
+ export type SnapshotUpdateMode = 'none' | 'new' | 'all'
89
+ export type TestWorkers = number | 'auto' | `${number}%`
90
+
91
+ export interface TestOptions {
92
+ root?: string
93
+ patterns?: string[]
94
+ namePattern?: string
95
+ projects?: string[]
96
+ environment?: TestEnvironment
97
+ watch?: boolean
98
+ changed?: boolean
99
+ related?: string[]
100
+ coverage?: boolean
101
+ updateSnapshots?: SnapshotUpdateMode
102
+ serial?: boolean
103
+ workers?: TestWorkers
104
+ bail?: number
105
+ shard?: `${number}/${number}`
106
+ seed?: string
107
+ shuffle?: boolean
108
+ reporter?: TestReporter
109
+ output?: string
110
+ allowNoTests?: boolean
111
+ browserPath?: string
112
+ headful?: boolean
113
+ }
114
+
115
+ export type TestCaseStatus = 'passed' | 'failed' | 'skipped' | 'todo'
116
+ export type TestSuiteStatus = 'passed' | 'failed' | 'skipped'
117
+ export type TestTerminationReason =
118
+ | 'completed'
119
+ | 'cancelled'
120
+ | 'bail'
121
+ | 'watch-restart'
122
+ | 'host-crash'
123
+ | 'timeout'
124
+ | 'oom'
125
+ | 'internal-error'
126
+
127
+ export interface TestLocation {
128
+ path: string
129
+ line: number
130
+ column: number
131
+ endLine: number | null
132
+ endColumn: number | null
133
+ }
134
+
135
+ export interface TestDiff {
136
+ expected: string | null
137
+ received: string | null
138
+ unified: string | null
139
+ }
140
+
141
+ export interface TestFailure {
142
+ message: string
143
+ code: string | null
144
+ stack: string | null
145
+ location: TestLocation | null
146
+ diff: TestDiff | null
147
+ }
148
+
149
+ export interface TestCaseResult {
150
+ id: string
151
+ name: string
152
+ fullName: string
153
+ status: TestCaseStatus
154
+ durationMs: number
155
+ assertions: number
156
+ attempts: number
157
+ location: TestLocation | null
158
+ failures: TestFailure[]
159
+ }
160
+
161
+ export interface SnapshotSummary {
162
+ added: number
163
+ matched: number
164
+ unmatched: number
165
+ updated: number
166
+ obsolete: number
167
+ filesRemoved: number
168
+ }
169
+
170
+ export interface CoverageMetric {
171
+ covered: number
172
+ total: number
173
+ percent: number
174
+ }
175
+
176
+ export interface CoverageMetrics {
177
+ lines: CoverageMetric
178
+ functions: CoverageMetric
179
+ blocks: CoverageMetric
180
+ }
181
+
182
+ export interface CoverageFile extends CoverageMetrics {
183
+ path: string
184
+ }
185
+
186
+ export interface CoverageResult {
187
+ summary: CoverageMetrics
188
+ files: CoverageFile[]
189
+ reportArtifactIds: string[]
190
+ }
191
+
192
+ export interface BrowserEnvironmentInfo {
193
+ name: string
194
+ version: string
195
+ headless: boolean
196
+ }
197
+
198
+ export interface TestEnvironmentInfo {
199
+ kind: 'dom' | 'browser'
200
+ react: string | null
201
+ reactDom: string | null
202
+ v8: string
203
+ browser: BrowserEnvironmentInfo | null
204
+ }
205
+
206
+ export type TestMetadataValue =
207
+ | null
208
+ | boolean
209
+ | number
210
+ | string
211
+ | TestMetadataValue[]
212
+ | { [key: string]: TestMetadataValue }
213
+
214
+ export interface TestArtifact {
215
+ id: string
216
+ kind: string
217
+ path: string
218
+ suiteId: string | null
219
+ testId: string | null
220
+ metadata: Record<string, TestMetadataValue>
221
+ }
222
+
223
+ export interface TestDiagnostic {
224
+ severity: 'error' | 'warning' | 'note' | 'help'
225
+ code: string
226
+ message: string
227
+ path: string | null
228
+ location: TestLocation | null
229
+ notes?: string[]
230
+ }
231
+
232
+ export interface TestLeak {
233
+ kind: 'timer' | 'listener' | 'task' | 'socket' | 'network' | 'other'
234
+ description: string
235
+ location: TestLocation | null
236
+ stack: string | null
237
+ }
238
+
239
+ export interface TestSuiteResult {
240
+ id: string
241
+ path: string
242
+ name: string | null
243
+ project: string | null
244
+ environment: TestEnvironmentInfo | null
245
+ status: TestSuiteStatus
246
+ durationMs: number
247
+ tests: TestCaseResult[]
248
+ failures: TestFailure[]
249
+ snapshot: SnapshotSummary | null
250
+ }
251
+
252
+ export interface TestStatusCounts {
253
+ total: number
254
+ passed: number
255
+ failed: number
256
+ skipped: number
257
+ }
258
+
259
+ export interface TestCaseStatusCounts extends TestStatusCounts {
260
+ todo: number
261
+ }
262
+
263
+ export interface TestRunCounts {
264
+ suites: TestStatusCounts
265
+ tests: TestCaseStatusCounts
266
+ }
267
+
268
+ export interface TestRunResult {
269
+ schemaVersion: 'wake.test.v1'
270
+ runId: string
271
+ success: boolean
272
+ seed: string
273
+ durationMs: number
274
+ terminationReason: TestTerminationReason
275
+ environment: TestEnvironmentInfo
276
+ suites: TestSuiteResult[]
277
+ counts: TestRunCounts
278
+ snapshot: SnapshotSummary
279
+ coverage: CoverageResult | null
280
+ leaks: TestLeak[]
281
+ artifacts: TestArtifact[]
282
+ diagnostics: TestDiagnostic[]
283
+ }
284
+
285
+ export interface TestRunStartEvent {
286
+ runId: string
287
+ watching: boolean
288
+ }
289
+
290
+ export interface TestCaseResultEvent {
291
+ runId: string
292
+ suiteId: string
293
+ result: TestCaseResult
294
+ }
295
+
296
+ export interface TestSuiteResultEvent {
297
+ runId: string
298
+ result: TestSuiteResult
299
+ }
300
+
301
+ export class TestContext extends EventEmitter {
302
+ private constructor()
303
+ readonly watching: boolean
304
+ readonly closed: boolean
305
+ run(): Promise<TestRunResult>
306
+ startWatch(): this
307
+ stopWatch(): this
308
+ close(): Promise<void>
309
+ [Symbol.asyncDispose](): Promise<void>
310
+ on(event: 'runStart', listener: (event: TestRunStartEvent) => void): this
311
+ on(event: 'testCaseResult', listener: (event: TestCaseResultEvent) => void): this
312
+ on(event: 'suiteResult', listener: (event: TestSuiteResultEvent) => void): this
313
+ on(event: 'runComplete', listener: (result: TestRunResult) => void): this
314
+ on(event: 'diagnostic', listener: (diagnostic: TestDiagnostic) => void): this
315
+ on(event: 'closed', listener: () => void): this
316
+ }
317
+
69
318
  export type BundlePlatform = 'browser' | 'node'
70
319
  export type BundleFormat = 'iife' | 'cjs'
71
320
  export type NodeTarget = `node${number}` | `node${number}.${number}`
@@ -183,6 +432,15 @@ export interface DocsDemo {
183
432
  warnings: string[]
184
433
  }
185
434
 
435
+ export interface DocsWorkspaceBuildInfo {
436
+ name: string
437
+ root: string
438
+ basePath: string
439
+ mode: 'components'
440
+ presentation: 'embedded' | 'standalone'
441
+ demos: number
442
+ }
443
+
186
444
  export interface DocsBuildOptions extends ProjectOptions {
187
445
  outdir?: string
188
446
  basePath?: string
@@ -193,6 +451,7 @@ export interface DocsBuildResult extends BuildResult {
193
451
  routes: DocsRoute[]
194
452
  mode: DocsMode
195
453
  demos: DocsDemo[]
454
+ workspaces: DocsWorkspaceBuildInfo[]
196
455
  }
197
456
 
198
457
  export interface DevServerOptions extends ProjectOptions {
@@ -208,6 +467,8 @@ export interface DocsDevServerOptions extends DevServerOptions {
208
467
  export interface DevServerRebuildStartEvent {
209
468
  type: 'rebuildStart'
210
469
  changedPaths: string[]
470
+ workspace?: string
471
+ basePath?: string
211
472
  }
212
473
 
213
474
  export interface DevServerRebuiltEvent {
@@ -219,6 +480,17 @@ export interface DevServerRebuiltEvent {
219
480
  chunks: number
220
481
  assets: number
221
482
  durationMs: number
483
+ workspace?: string
484
+ basePath?: string
485
+ }
486
+
487
+ export interface DevServerWorkspaceStateEvent {
488
+ type: 'workspaceState'
489
+ total: number
490
+ loaded: number
491
+ failed: number
492
+ current?: string
493
+ failedNames: string[]
222
494
  }
223
495
 
224
496
  export class BuildContext {
@@ -237,6 +509,7 @@ export class DevServer extends EventEmitter {
237
509
  [Symbol.asyncDispose](): Promise<void>
238
510
  on(event: 'rebuildStart', listener: (event: DevServerRebuildStartEvent) => void): this
239
511
  on(event: 'rebuilt', listener: (event: DevServerRebuiltEvent) => void): this
512
+ on(event: 'workspaceState', listener: (event: DevServerWorkspaceStateEvent) => void): this
240
513
  on(event: 'diagnostic', listener: (diagnostic: Diagnostic) => void): this
241
514
  on(event: 'closed', listener: () => void): this
242
515
  }
@@ -248,6 +521,8 @@ export function buildLibrary(options?: LibraryBuildOptions): Promise<LibraryBuil
248
521
  export function generateCssToken(options?: GenerateCssTokenOptions): Promise<GenerateCssTokenResult>
249
522
  export function generateDocgen(options?: GenerateDocgenOptions): Promise<GenerateDocgenResult>
250
523
  export function createBuildContext(options?: BuildOptions): Promise<BuildContext>
524
+ export function runTests(options?: TestOptions & { signal?: AbortSignal }): Promise<TestRunResult>
525
+ export function createTestContext(options?: TestOptions): Promise<TestContext>
251
526
  export function startDevServer(options?: DevServerOptions): Promise<DevServer>
252
527
  export function buildDocs(options?: DocsBuildOptions): Promise<DocsBuildResult>
253
528
  export function startDocsDevServer(options?: DocsDevServerOptions): Promise<DevServer>
@@ -255,6 +530,7 @@ export function startDocsDevServer(options?: DocsDevServerOptions): Promise<DevS
255
530
  declare const wake: {
256
531
  BuildContext: typeof BuildContext
257
532
  DevServer: typeof DevServer
533
+ TestContext: typeof TestContext
258
534
  WakeError: typeof WakeError
259
535
  build: typeof build
260
536
  buildLibrary: typeof buildLibrary
@@ -263,6 +539,8 @@ declare const wake: {
263
539
  generateCssToken: typeof generateCssToken
264
540
  generateDocgen: typeof generateDocgen
265
541
  createBuildContext: typeof createBuildContext
542
+ runTests: typeof runTests
543
+ createTestContext: typeof createTestContext
266
544
  startDevServer: typeof startDevServer
267
545
  startDocsDevServer: typeof startDocsDevServer
268
546
  version: typeof version
package/index.mjs CHANGED
@@ -3,14 +3,17 @@ import api from './index.cjs'
3
3
  export const {
4
4
  BuildContext,
5
5
  DevServer,
6
+ TestContext,
6
7
  WakeError,
7
8
  build,
8
9
  buildLibrary,
9
10
  buildDocs,
10
11
  bundle,
12
+ runTests,
11
13
  generateCssToken,
12
14
  generateDocgen,
13
15
  createBuildContext,
16
+ createTestContext,
14
17
  startDevServer,
15
18
  startDocsDevServer,
16
19
  version,
package/loader.cjs CHANGED
@@ -17,9 +17,25 @@ function unsupported(message, cause) {
17
17
  return error
18
18
  }
19
19
 
20
+ function attachTestHost(native, nativePath) {
21
+ const hostPath = process.env.WAKE_TEST_HOST_PATH || path.join(
22
+ path.dirname(nativePath),
23
+ 'test-host',
24
+ process.platform === 'win32' ? 'wake-test-host.exe' : 'wake-test-host',
25
+ )
26
+ Object.defineProperty(native, '__wakeTestHostPath', {
27
+ configurable: false,
28
+ enumerable: false,
29
+ writable: false,
30
+ value: hostPath,
31
+ })
32
+ return native
33
+ }
34
+
20
35
  function loadNative() {
21
36
  if (process.env.WAKE_NATIVE_PATH) {
22
- return require(path.resolve(process.env.WAKE_NATIVE_PATH))
37
+ const nativePath = path.resolve(process.env.WAKE_NATIVE_PATH)
38
+ return attachTestHost(require(nativePath), nativePath)
23
39
  }
24
40
 
25
41
  const key = `${process.platform}-${process.arch}`
@@ -41,7 +57,8 @@ function loadNative() {
41
57
  }
42
58
 
43
59
  try {
44
- return require(packageName)
60
+ const nativePath = require.resolve(packageName)
61
+ return attachTestHost(require(nativePath), nativePath)
45
62
  } catch (cause) {
46
63
  throw unsupported(
47
64
  `Unable to load ${packageName} for ${process.platform}/${process.arch}. ` +
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@crab-dev/wake",
3
- "version": "0.1.20",
3
+ "version": "0.1.22",
4
4
  "description": "Wake native web build tools for Node.js",
5
5
  "license": "MIT OR Apache-2.0",
6
6
  "repository": {
@@ -22,6 +22,16 @@
22
22
  "import": "./experimental.mjs",
23
23
  "require": "./experimental.cjs"
24
24
  },
25
+ "./test": {
26
+ "types": "./test.d.ts",
27
+ "import": "./test.mjs",
28
+ "require": "./test.cjs"
29
+ },
30
+ "./test/react": {
31
+ "types": "./test-react.d.ts",
32
+ "import": "./test-react.mjs",
33
+ "require": "./test-react.cjs"
34
+ },
25
35
  "./internal/components-runtime": {
26
36
  "types": "./internal/components-runtime.d.ts",
27
37
  "import": "./internal/components-runtime.mjs"
@@ -41,6 +51,12 @@
41
51
  "*.mjs",
42
52
  "index.d.ts",
43
53
  "experimental.d.ts",
54
+ "test.cjs",
55
+ "test.mjs",
56
+ "test.d.ts",
57
+ "test-react.cjs",
58
+ "test-react.mjs",
59
+ "test-react.d.ts",
44
60
  "README.md",
45
61
  "CHANGELOG.md",
46
62
  "LICENSE-MIT",
@@ -50,7 +66,7 @@
50
66
  "node": ">=22.14 <27"
51
67
  },
52
68
  "dependencies": {
53
- "@crab-dev/css": "0.1.20",
69
+ "@crab-dev/css": "0.1.22",
54
70
  "@crab-dev/rc-alert": "^0.0.2",
55
71
  "@crab-dev/rc-button": "^0.0.2",
56
72
  "@crab-dev/rc-dialog": "^0.0.2",
@@ -71,15 +87,15 @@
71
87
  "string-width": "8.2.2"
72
88
  },
73
89
  "peerDependencies": {
74
- "react": "^19.2.8",
75
- "react-dom": "^19.2.8"
90
+ "react": ">=19.2.8 <19.3.0",
91
+ "react-dom": ">=19.2.8 <19.3.0"
76
92
  },
77
93
  "optionalDependencies": {
78
- "@crab-dev/wake-darwin-arm64": "0.1.20",
79
- "@crab-dev/wake-darwin-x64": "0.1.20",
80
- "@crab-dev/wake-linux-arm64-gnu": "0.1.20",
81
- "@crab-dev/wake-linux-x64-gnu": "0.1.20",
82
- "@crab-dev/wake-win32-x64-msvc": "0.1.20"
94
+ "@crab-dev/wake-darwin-arm64": "0.1.22",
95
+ "@crab-dev/wake-darwin-x64": "0.1.22",
96
+ "@crab-dev/wake-linux-arm64-gnu": "0.1.22",
97
+ "@crab-dev/wake-linux-x64-gnu": "0.1.22",
98
+ "@crab-dev/wake-win32-x64-msvc": "0.1.22"
83
99
  },
84
100
  "publishConfig": {
85
101
  "access": "public",