@rivetkit/rivetkit-napi 0.0.0-runner-config-drain-grace-threshold.e1be3d6 → 0.0.0-sql-metrics.eac581d
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.d.ts +145 -10
- package/index.js +4 -1
- package/package.json +15 -10
- package/scripts/build.mjs +8 -0
package/index.d.ts
CHANGED
|
@@ -23,10 +23,16 @@ export interface StateDeltaPayload {
|
|
|
23
23
|
connHibernation: Array<StateDeltaConnHibernationEntry>
|
|
24
24
|
connHibernationRemoved: Array<string>
|
|
25
25
|
}
|
|
26
|
+
export interface WorkflowKvWritePayload {
|
|
27
|
+
key: Buffer
|
|
28
|
+
value: Buffer
|
|
29
|
+
}
|
|
26
30
|
export interface JsRequestSaveOpts {
|
|
27
31
|
immediate?: boolean
|
|
28
32
|
maxWaitMs?: number
|
|
29
33
|
}
|
|
34
|
+
export declare function decodeInspectorRequest(bytes: Buffer, advertisedVersion: number): Buffer
|
|
35
|
+
export declare function encodeInspectorResponse(bytes: Buffer, targetVersion: number): Buffer
|
|
30
36
|
export interface JsInspectorSnapshot {
|
|
31
37
|
stateRevision: number
|
|
32
38
|
connectionsRevision: number
|
|
@@ -35,6 +41,9 @@ export interface JsInspectorSnapshot {
|
|
|
35
41
|
queueSize: number
|
|
36
42
|
connectedClients: number
|
|
37
43
|
}
|
|
44
|
+
export interface JsActorRuntimeSocketEndpointInfo {
|
|
45
|
+
path: string
|
|
46
|
+
}
|
|
38
47
|
export interface JsHttpResponse {
|
|
39
48
|
status?: number
|
|
40
49
|
headers?: Record<string, string>
|
|
@@ -47,11 +56,50 @@ export interface JsQueueSendResult {
|
|
|
47
56
|
export interface JsActionDefinition {
|
|
48
57
|
name: string
|
|
49
58
|
}
|
|
59
|
+
/**
|
|
60
|
+
* One entry in the actor's `inspector.tabs[]` declaration. Either a
|
|
61
|
+
* custom-tab descriptor (id + label + source dir) or a built-in modifier
|
|
62
|
+
* (id + hidden=true). Validation already happened on the TS side; the
|
|
63
|
+
* runtime just splits the discriminator.
|
|
64
|
+
*/
|
|
65
|
+
export interface JsInspectorTabEntry {
|
|
66
|
+
id: string
|
|
67
|
+
/** Required for custom entries; omitted for HideBuiltin. */
|
|
68
|
+
label?: string
|
|
69
|
+
/** Required for custom entries — absolute path to the source directory. */
|
|
70
|
+
source?: string
|
|
71
|
+
/**
|
|
72
|
+
* Optional icon id for custom entries. Dashboard maps strings to
|
|
73
|
+
* glyphs; unknown ids fall back to a generic icon.
|
|
74
|
+
*/
|
|
75
|
+
icon?: string
|
|
76
|
+
/** Set to true for HideBuiltin entries. */
|
|
77
|
+
hidden?: boolean
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Experimental SQLite profiling configuration. This entire configuration
|
|
81
|
+
* surface is subject to change without notice.
|
|
82
|
+
*/
|
|
83
|
+
export interface JsSqliteProfilingConfig {
|
|
84
|
+
enabled?: boolean
|
|
85
|
+
maxTrackedStatementFingerprints?: number
|
|
86
|
+
maxTrackedTransactionFingerprints?: number
|
|
87
|
+
maxPrometheusSeries?: number
|
|
88
|
+
maxStatementsPerTransactionTrace?: number
|
|
89
|
+
maxGetPagesRequestsPerTrace?: number
|
|
90
|
+
maxTransactionNameBytes?: number
|
|
91
|
+
slowOperationThresholdMs?: number
|
|
92
|
+
baselineSampleRate?: number
|
|
93
|
+
maxDiagnosticEventsPerMinute?: number
|
|
94
|
+
diagnosticEventQueueCapacity?: number
|
|
95
|
+
}
|
|
50
96
|
export interface JsActorConfig {
|
|
51
97
|
name?: string
|
|
52
98
|
icon?: string
|
|
53
99
|
hasDatabase?: boolean
|
|
54
100
|
remoteSqlite?: boolean
|
|
101
|
+
sqliteProfiling?: JsSqliteProfilingConfig
|
|
102
|
+
enableActorRuntimeSocket?: boolean
|
|
55
103
|
hasState?: boolean
|
|
56
104
|
canHibernateWebsocket?: boolean
|
|
57
105
|
stateSaveIntervalMs?: number
|
|
@@ -72,12 +120,12 @@ export interface JsActorConfig {
|
|
|
72
120
|
connectionLivenessTimeoutMs?: number
|
|
73
121
|
connectionLivenessIntervalMs?: number
|
|
74
122
|
maxQueueSize?: number
|
|
123
|
+
maxSchedules?: number
|
|
75
124
|
maxQueueMessageSize?: number
|
|
76
125
|
maxIncomingMessageSize?: number
|
|
77
126
|
maxOutgoingMessageSize?: number
|
|
78
|
-
preloadMaxWorkflowBytes?: number
|
|
79
|
-
preloadMaxConnectionsBytes?: number
|
|
80
127
|
actions?: Array<JsActionDefinition>
|
|
128
|
+
inspectorTabs?: Array<JsInspectorTabEntry>
|
|
81
129
|
}
|
|
82
130
|
export interface JsBindParam {
|
|
83
131
|
kind: string
|
|
@@ -99,6 +147,10 @@ export interface NativeExecuteResult {
|
|
|
99
147
|
changes: number
|
|
100
148
|
lastInsertRowId?: number
|
|
101
149
|
}
|
|
150
|
+
export interface JsSqliteBatchStatement {
|
|
151
|
+
sql: string
|
|
152
|
+
params?: Array<JsBindParam>
|
|
153
|
+
}
|
|
102
154
|
export interface JsSqliteVfsMetrics {
|
|
103
155
|
requestBuildNs: number
|
|
104
156
|
serializeNs: number
|
|
@@ -155,6 +207,8 @@ export interface JsServeConfig {
|
|
|
155
207
|
namespace: string
|
|
156
208
|
poolName: string
|
|
157
209
|
engineBinaryPath?: string
|
|
210
|
+
engineHost?: string
|
|
211
|
+
enginePort?: number
|
|
158
212
|
handleInspectorHttpInRuntime?: boolean
|
|
159
213
|
serverlessBasePath?: string
|
|
160
214
|
serverlessPackageVersion: string
|
|
@@ -164,6 +218,16 @@ export interface JsServeConfig {
|
|
|
164
218
|
serverlessValidateEndpoint: boolean
|
|
165
219
|
serverlessMaxStartPayloadBytes: number
|
|
166
220
|
}
|
|
221
|
+
export interface JsListenerConfig {
|
|
222
|
+
/** Host to bind. Defaults to `0.0.0.0` when not provided. */
|
|
223
|
+
host?: string
|
|
224
|
+
port: number
|
|
225
|
+
/**
|
|
226
|
+
* Optional static file root mounted as a fallback below the framework
|
|
227
|
+
* routes.
|
|
228
|
+
*/
|
|
229
|
+
publicDir?: string
|
|
230
|
+
}
|
|
167
231
|
export interface JsServerlessRequest {
|
|
168
232
|
method: string
|
|
169
233
|
url: string
|
|
@@ -174,15 +238,53 @@ export interface JsServerlessResponseHead {
|
|
|
174
238
|
status: number
|
|
175
239
|
headers: Record<string, string>
|
|
176
240
|
}
|
|
177
|
-
export interface
|
|
178
|
-
|
|
179
|
-
|
|
241
|
+
export interface JsApplicationResponse {
|
|
242
|
+
status: number
|
|
243
|
+
headers: Record<string, string>
|
|
244
|
+
body: Buffer
|
|
245
|
+
}
|
|
246
|
+
export interface JsRegistryRouteResponse {
|
|
247
|
+
status: number
|
|
248
|
+
headers: Record<string, string>
|
|
249
|
+
body: Buffer
|
|
180
250
|
}
|
|
181
251
|
export interface JsServerlessStreamError {
|
|
182
252
|
group: string
|
|
183
253
|
code: string
|
|
184
254
|
message: string
|
|
185
255
|
}
|
|
256
|
+
export interface JsScheduledEventInfo {
|
|
257
|
+
id: string
|
|
258
|
+
action: string
|
|
259
|
+
args: Buffer
|
|
260
|
+
runAt: number
|
|
261
|
+
}
|
|
262
|
+
export interface JsCronJobInfo {
|
|
263
|
+
name: string
|
|
264
|
+
kind: string
|
|
265
|
+
action: string
|
|
266
|
+
args: Buffer
|
|
267
|
+
nextRunAt: number
|
|
268
|
+
lastRunAt?: number
|
|
269
|
+
expression?: string
|
|
270
|
+
timezone?: string
|
|
271
|
+
intervalMs?: number
|
|
272
|
+
maxHistory: number
|
|
273
|
+
}
|
|
274
|
+
export interface JsScheduleErrorInfo {
|
|
275
|
+
group: string
|
|
276
|
+
code: string
|
|
277
|
+
message: string
|
|
278
|
+
metadata?: any
|
|
279
|
+
}
|
|
280
|
+
export interface JsCronFire {
|
|
281
|
+
action: string
|
|
282
|
+
scheduledAt: number
|
|
283
|
+
firedAt: number
|
|
284
|
+
finishedAt?: number
|
|
285
|
+
result: string
|
|
286
|
+
error?: JsScheduleErrorInfo
|
|
287
|
+
}
|
|
186
288
|
/** Options for KV list operations. */
|
|
187
289
|
export interface JsKvListOptions {
|
|
188
290
|
reverse?: boolean
|
|
@@ -195,12 +297,12 @@ export interface JsKvEntry {
|
|
|
195
297
|
}
|
|
196
298
|
/** N-API wrapper around `rivetkit-core::ActorContext`. */
|
|
197
299
|
export declare class ActorContext {
|
|
198
|
-
constructor(actorId: string, name: string, region: string)
|
|
199
300
|
state(): Buffer
|
|
200
301
|
beginOnStateChange(): void
|
|
201
302
|
endOnStateChange(): void
|
|
202
303
|
kv(): Kv
|
|
203
304
|
sql(): JsNativeDatabase
|
|
305
|
+
provisionActorRuntimeSocket(): Promise<JsActorRuntimeSocketEndpointInfo>
|
|
204
306
|
schedule(): Schedule
|
|
205
307
|
queue(): Queue
|
|
206
308
|
setAlarm(timestampMs?: number | undefined | null): void
|
|
@@ -215,6 +317,7 @@ export declare class ActorContext {
|
|
|
215
317
|
takePendingHibernationChanges(): Array<string>
|
|
216
318
|
dirtyHibernatableConns(): Array<ConnHandle>
|
|
217
319
|
saveState(payload: StateDeltaPayload): Promise<void>
|
|
320
|
+
saveStateAndWorkflowBatch(writes: Array<WorkflowKvWritePayload>): Promise<void>
|
|
218
321
|
actorId(): string
|
|
219
322
|
name(): string
|
|
220
323
|
key(): Array<JsActorKeySegment>
|
|
@@ -240,6 +343,8 @@ export declare class ActorContext {
|
|
|
240
343
|
disconnectConns(predicate: (...args: any[]) => any): Promise<void>
|
|
241
344
|
broadcast(name: string, args: Buffer): void
|
|
242
345
|
waitUntil(promise: Promise<any>): void
|
|
346
|
+
waitForTrackedShutdownWork(): Promise<boolean>
|
|
347
|
+
waitForTrackedShutdownWorkUnbounded(): Promise<void>
|
|
243
348
|
registerTask(promise: Promise<any>): void
|
|
244
349
|
runtimeState(): object
|
|
245
350
|
clearRuntimeState(): void
|
|
@@ -268,8 +373,16 @@ export declare class JsNativeDatabase {
|
|
|
268
373
|
run(sql: string, params?: Array<JsBindParam> | undefined | null): Promise<ExecuteResult>
|
|
269
374
|
query(sql: string, params?: Array<JsBindParam> | undefined | null): Promise<QueryResult>
|
|
270
375
|
execute(sql: string, params?: Array<JsBindParam> | undefined | null): Promise<NativeExecuteResult>
|
|
376
|
+
executeBatch(statements: Array<JsSqliteBatchStatement>): Promise<Array<NativeExecuteResult>>
|
|
271
377
|
exec(sql: string): Promise<QueryResult>
|
|
272
378
|
close(): Promise<void>
|
|
379
|
+
beginTransaction(timeoutMs?: number | undefined | null, name?: string | undefined | null): Promise<JsSqliteTransaction>
|
|
380
|
+
}
|
|
381
|
+
export declare class JsSqliteTransaction {
|
|
382
|
+
execute(sql: string, params?: Array<JsBindParam> | undefined | null): Promise<NativeExecuteResult>
|
|
383
|
+
exec(sql: string): Promise<QueryResult>
|
|
384
|
+
commit(): Promise<void>
|
|
385
|
+
rollback(): Promise<void>
|
|
273
386
|
}
|
|
274
387
|
export declare class Kv {
|
|
275
388
|
get(key: Buffer): Promise<Buffer | null>
|
|
@@ -287,11 +400,12 @@ export declare class Queue {
|
|
|
287
400
|
next(options?: JsQueueNextOptions | undefined | null, signal?: CancellationToken | undefined | null): Promise<QueueMessage | null>
|
|
288
401
|
nextBatch(options?: JsQueueNextBatchOptions | undefined | null, signal?: CancellationToken | undefined | null): Promise<Array<QueueMessage>>
|
|
289
402
|
waitForNames(names: Array<string>, options?: JsQueueWaitOptions | undefined | null, signal?: CancellationToken | undefined | null): Promise<QueueMessage>
|
|
290
|
-
waitForNamesAvailable(names: Array<string>, options?: JsQueueWaitOptions | undefined | null): Promise<void>
|
|
403
|
+
waitForNamesAvailable(names: Array<string>, options?: JsQueueWaitOptions | undefined | null, signal?: CancellationToken | undefined | null): Promise<void>
|
|
291
404
|
enqueueAndWait(name: string, body: Buffer, options?: JsQueueEnqueueAndWaitOptions | undefined | null, signal?: CancellationToken | undefined | null): Promise<Buffer | null>
|
|
292
405
|
tryNext(options?: JsQueueTryNextOptions | undefined | null): QueueMessage | null
|
|
293
406
|
tryNextBatch(options?: JsQueueTryNextBatchOptions | undefined | null): Array<QueueMessage>
|
|
294
407
|
maxSize(): number
|
|
408
|
+
reset(): Promise<void>
|
|
295
409
|
inspectMessages(): Promise<Array<JsQueueInspectMessage>>
|
|
296
410
|
}
|
|
297
411
|
export declare class QueueMessage {
|
|
@@ -306,6 +420,13 @@ export declare class CoreRegistry {
|
|
|
306
420
|
constructor()
|
|
307
421
|
register(name: string, factory: NapiActorFactory): void
|
|
308
422
|
serve(config: JsServeConfig): Promise<void>
|
|
423
|
+
/**
|
|
424
|
+
* Wait until the serverful envoy has completed its Engine registration.
|
|
425
|
+
*
|
|
426
|
+
* Readiness is the envoy client's `ToEnvoyInit` signal, not HTTP health or
|
|
427
|
+
* merely constructing the envoy handle.
|
|
428
|
+
*/
|
|
429
|
+
waitReady(): Promise<void>
|
|
309
430
|
/**
|
|
310
431
|
* Trip the shutdown token and tear down any live serverless runtime.
|
|
311
432
|
*
|
|
@@ -314,12 +435,26 @@ export declare class CoreRegistry {
|
|
|
314
435
|
* separately to avoid re-entrancy.
|
|
315
436
|
*/
|
|
316
437
|
shutdown(): Promise<void>
|
|
317
|
-
|
|
438
|
+
actorStopThresholdMs(): Promise<number | null>
|
|
439
|
+
health(): Promise<JsRegistryRouteResponse>
|
|
440
|
+
metadata(): JsRegistryRouteResponse
|
|
441
|
+
metrics(): JsRegistryRouteResponse
|
|
442
|
+
serveApplicationListener(listener: JsListenerConfig, application: (...args: any[]) => any, config: JsServeConfig): Promise<void>
|
|
443
|
+
serveListener(listener: JsListenerConfig, config: JsServeConfig, application?: (...args: any[]) => any | undefined | null): Promise<void>
|
|
318
444
|
handleServerlessRequest(req: JsServerlessRequest, onStreamEvent: (...args: any[]) => any, cancelToken: CancellationToken, config: JsServeConfig): Promise<JsServerlessResponseHead>
|
|
319
445
|
}
|
|
320
446
|
export declare class Schedule {
|
|
321
|
-
after(durationMs: number, actionName: string, args: Buffer):
|
|
322
|
-
at(timestampMs: number, actionName: string, args: Buffer):
|
|
447
|
+
after(durationMs: number, actionName: string, args: Buffer): Promise<string>
|
|
448
|
+
at(timestampMs: number, actionName: string, args: Buffer): Promise<string>
|
|
449
|
+
cancel(id: string): Promise<boolean>
|
|
450
|
+
get(id: string): Promise<JsScheduledEventInfo | null>
|
|
451
|
+
list(): Promise<Array<JsScheduledEventInfo>>
|
|
452
|
+
cronSet(name: string, expression: string, timezone: string | undefined | null, actionName: string, args: Buffer, maxHistory?: number | undefined | null): Promise<void>
|
|
453
|
+
cronEvery(name: string, intervalMs: number, actionName: string, args: Buffer, maxHistory?: number | undefined | null): Promise<void>
|
|
454
|
+
cronGet(name: string): Promise<JsCronJobInfo | null>
|
|
455
|
+
cronList(): Promise<Array<JsCronJobInfo>>
|
|
456
|
+
cronDelete(name: string): Promise<boolean>
|
|
457
|
+
cronHistory(name: string, limit?: number | undefined | null): Promise<Array<JsCronFire>>
|
|
323
458
|
}
|
|
324
459
|
export declare class WebSocket {
|
|
325
460
|
send(data: Buffer, binary: boolean): void
|
package/index.js
CHANGED
|
@@ -310,13 +310,16 @@ if (!nativeBinding) {
|
|
|
310
310
|
throw new Error(`Failed to load native binding`)
|
|
311
311
|
}
|
|
312
312
|
|
|
313
|
-
const { ActorContext, NapiActorFactory, CancellationToken, ConnHandle, JsNativeDatabase, Kv, Queue, QueueMessage, CoreRegistry, Schedule, WebSocket } = nativeBinding
|
|
313
|
+
const { ActorContext, decodeInspectorRequest, encodeInspectorResponse, NapiActorFactory, CancellationToken, ConnHandle, JsNativeDatabase, JsSqliteTransaction, Kv, Queue, QueueMessage, CoreRegistry, Schedule, WebSocket } = nativeBinding
|
|
314
314
|
|
|
315
315
|
module.exports.ActorContext = ActorContext
|
|
316
|
+
module.exports.decodeInspectorRequest = decodeInspectorRequest
|
|
317
|
+
module.exports.encodeInspectorResponse = encodeInspectorResponse
|
|
316
318
|
module.exports.NapiActorFactory = NapiActorFactory
|
|
317
319
|
module.exports.CancellationToken = CancellationToken
|
|
318
320
|
module.exports.ConnHandle = ConnHandle
|
|
319
321
|
module.exports.JsNativeDatabase = JsNativeDatabase
|
|
322
|
+
module.exports.JsSqliteTransaction = JsSqliteTransaction
|
|
320
323
|
module.exports.Kv = Kv
|
|
321
324
|
module.exports.Queue = Queue
|
|
322
325
|
module.exports.QueueMessage = QueueMessage
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@rivetkit/rivetkit-napi",
|
|
3
|
-
"version": "0.0.0-
|
|
3
|
+
"version": "0.0.0-sql-metrics.eac581d",
|
|
4
4
|
"description": "Native N-API addon for RivetKit providing envoy client and SQLite access",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"main": "index.js",
|
|
@@ -39,19 +39,24 @@
|
|
|
39
39
|
"build": "node scripts/build.mjs",
|
|
40
40
|
"build:release": "node scripts/build.mjs --release",
|
|
41
41
|
"build:force": "node scripts/build.mjs --force",
|
|
42
|
-
"build:force:release": "node scripts/build.mjs --force --release"
|
|
42
|
+
"build:force:release": "node scripts/build.mjs --force --release",
|
|
43
|
+
"build:embed": "node scripts/build.mjs"
|
|
43
44
|
},
|
|
44
45
|
"dependencies": {
|
|
45
46
|
"@napi-rs/cli": "^2.18.4",
|
|
46
|
-
"@rivetkit/engine-envoy-protocol": "0.0.0-
|
|
47
|
+
"@rivetkit/engine-envoy-protocol": "0.0.0-sql-metrics.eac581d"
|
|
48
|
+
},
|
|
49
|
+
"repository": {
|
|
50
|
+
"type": "git",
|
|
51
|
+
"url": "https://github.com/rivet-dev/actors.git",
|
|
52
|
+
"directory": "rivetkit-typescript/packages/rivetkit-napi"
|
|
47
53
|
},
|
|
48
54
|
"optionalDependencies": {
|
|
49
|
-
"@rivetkit/rivetkit-napi-darwin-arm64": "0.0.0-
|
|
50
|
-
"@rivetkit/rivetkit-napi-darwin-x64": "0.0.0-
|
|
51
|
-
"@rivetkit/rivetkit-napi-linux-arm64-gnu": "0.0.0-
|
|
52
|
-
"@rivetkit/rivetkit-napi-linux-arm64-musl": "0.0.0-
|
|
53
|
-
"@rivetkit/rivetkit-napi-linux-x64-gnu": "0.0.0-
|
|
54
|
-
"@rivetkit/rivetkit-napi-linux-x64-musl": "0.0.0-
|
|
55
|
-
"@rivetkit/rivetkit-napi-win32-x64-msvc": "0.0.0-runner-config-drain-grace-threshold.e1be3d6"
|
|
55
|
+
"@rivetkit/rivetkit-napi-darwin-arm64": "0.0.0-sql-metrics.eac581d",
|
|
56
|
+
"@rivetkit/rivetkit-napi-darwin-x64": "0.0.0-sql-metrics.eac581d",
|
|
57
|
+
"@rivetkit/rivetkit-napi-linux-arm64-gnu": "0.0.0-sql-metrics.eac581d",
|
|
58
|
+
"@rivetkit/rivetkit-napi-linux-arm64-musl": "0.0.0-sql-metrics.eac581d",
|
|
59
|
+
"@rivetkit/rivetkit-napi-linux-x64-gnu": "0.0.0-sql-metrics.eac581d",
|
|
60
|
+
"@rivetkit/rivetkit-napi-linux-x64-musl": "0.0.0-sql-metrics.eac581d"
|
|
56
61
|
}
|
|
57
62
|
}
|
package/scripts/build.mjs
CHANGED
|
@@ -16,6 +16,14 @@ if (process.env.SKIP_NAPI_BUILD === "1") {
|
|
|
16
16
|
process.exit(0);
|
|
17
17
|
}
|
|
18
18
|
|
|
19
|
+
// The per-actor inspector UI (frontend/dist/inspector-ui, embedded into
|
|
20
|
+
// rivetkit-core by its build.rs) must be built before this napi build runs.
|
|
21
|
+
// It is NOT built here: rivetkit-core's embed needs rivetkit/inspector-tab,
|
|
22
|
+
// which is downstream of this package in the build graph, so building it from
|
|
23
|
+
// the napi build would invert the dependency order. CI builds it via
|
|
24
|
+
// `turbo build:inspector-ui` in docker/build/*.Dockerfile before `napi build`;
|
|
25
|
+
// for local builds run `pnpm -F @rivetkit/engine-frontend build:inspector-ui`
|
|
26
|
+
// (or `turbo build:inspector-ui`) first.
|
|
19
27
|
const cmd = ["build", "--platform", ...extraFlags];
|
|
20
28
|
console.log(`[rivetkit-napi/build] running: napi ${cmd.join(" ")}`);
|
|
21
29
|
execFileSync("napi", cmd, { stdio: "inherit" });
|