@superpanel-sdk/runtime 0.5.0 → 0.7.0
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/README.md +3 -3
- package/dist/builder/codegen/emit.d.ts +5 -10
- package/dist/builder/codegen/emit.js +100 -106
- package/dist/builder/codegen/generate.d.ts +3 -5
- package/dist/builder/codegen/generate.js +13 -32
- package/dist/builder/company-imports.d.ts +5 -0
- package/dist/builder/company-imports.js +9 -1
- package/dist/builder/compile/compile-sequence.d.ts +13 -11
- package/dist/builder/compile/compile-sequence.js +135 -83
- package/dist/builder/compile/function-code.d.ts +15 -9
- package/dist/builder/compile/function-code.js +59 -29
- package/dist/builder/compile/registry.d.ts +4 -4
- package/dist/builder/compile/registry.js +14 -12
- package/dist/builder/errors.d.ts +9 -0
- package/dist/builder/errors.js +17 -0
- package/dist/builder/function-params.d.ts +10 -0
- package/dist/builder/function-params.js +203 -0
- package/dist/builder/load.d.ts +17 -17
- package/dist/builder/load.js +27 -25
- package/dist/builder/paths.d.ts +6 -1
- package/dist/builder/paths.js +16 -2
- package/dist/builder/schedules.d.ts +9 -7
- package/dist/builder/schedules.js +20 -21
- package/dist/builder/typecheck.d.ts +1 -1
- package/dist/builder/typecheck.js +3 -6
- package/dist/builder/types.d.ts +41 -5
- package/dist/builder/types.js +19 -0
- package/dist/cli/calls/index.d.ts +177 -0
- package/dist/cli/calls/index.js +96 -0
- package/dist/cli/debug/index.d.ts +31 -0
- package/dist/cli/debug/index.js +119 -0
- package/dist/cli/exec/index.d.ts +39 -0
- package/dist/cli/exec/index.js +138 -0
- package/dist/cli/exec/session.d.ts +48 -0
- package/dist/cli/exec/session.js +82 -0
- package/dist/cli/exec/trace.d.ts +18 -0
- package/dist/cli/exec/trace.js +52 -0
- package/dist/cli/index.js +84 -1
- package/dist/cli/logs/index.d.ts +47 -0
- package/dist/cli/logs/index.js +113 -0
- package/dist/cli/mobile/index.d.ts +12 -0
- package/dist/cli/mobile/index.js +405 -0
- package/dist/cli/serve/index.d.ts +40 -4
- package/dist/cli/serve/index.js +167 -28
- package/dist/cli/turns/index.d.ts +105 -0
- package/dist/cli/turns/index.js +128 -0
- package/dist/cli/turns/run.d.ts +13 -0
- package/dist/cli/turns/run.js +57 -0
- package/dist/cli/turns/shadow.d.ts +112 -0
- package/dist/cli/turns/shadow.js +54 -0
- package/dist/cli/type-gen/index.js +0 -1
- package/dist/compute-host/compute-host.d.ts +5 -6
- package/dist/compute-host/compute-host.js +4 -13
- package/dist/compute-host/source-compute-host.d.ts +5 -7
- package/dist/compute-host/source-compute-host.js +12 -33
- package/dist/core/case-orchestrator/contact-hours.d.ts +26 -6
- package/dist/core/case-orchestrator/contact-hours.js +27 -8
- package/dist/core/case-orchestrator/index.d.ts +1 -4
- package/dist/core/case-orchestrator/index.js +1 -4
- package/dist/core/case-orchestrator/render.d.ts +1 -1
- package/dist/core/case-orchestrator/render.js +15 -10
- package/dist/core/case-orchestrator/types.d.ts +83 -128
- package/dist/core/case-orchestrator/types.js +0 -4
- package/dist/core/context/email-message.d.ts +40 -1
- package/dist/core/context/email-message.js +27 -0
- package/dist/core/context/email.d.ts +13 -1
- package/dist/core/context/email.js +2 -3
- package/dist/core/context/exchanges.d.ts +25 -0
- package/dist/core/context/exchanges.js +25 -7
- package/dist/core/context/instances.d.ts +31 -2
- package/dist/core/context/instances.js +18 -4
- package/dist/core/context/platform-registry.d.ts +35 -0
- package/dist/core/context/sms.d.ts +30 -0
- package/dist/core/context/sms.js +20 -0
- package/dist/core/context/types.d.ts +29 -1
- package/dist/core/conversation/index.d.ts +58 -4
- package/dist/core/conversation/index.js +123 -4
- package/dist/core/functions/errors.d.ts +74 -0
- package/dist/core/functions/errors.js +26 -0
- package/dist/core/functions/events.d.ts +23 -78
- package/dist/core/functions/events.js +8 -17
- package/dist/core/functions/schedules.d.ts +9 -10
- package/dist/core/functions/schedules.js +2 -2
- package/dist/core/functions/types.d.ts +17 -72
- package/dist/core/functions/types.js +1 -9
- package/dist/core/page/define.d.ts +230 -160
- package/dist/core/page/define.js +145 -104
- package/dist/core/page/envelope.d.ts +55 -0
- package/dist/core/page/envelope.js +4 -0
- package/dist/core/page/fns.d.ts +448 -0
- package/dist/core/page/fns.js +539 -0
- package/dist/core/page/memory-reader.d.ts +27 -0
- package/dist/core/page/memory-reader.js +299 -0
- package/dist/core/page/page-host.d.ts +20 -0
- package/dist/core/page/page-host.js +57 -0
- package/dist/core/page/records-query.d.ts +234 -0
- package/dist/core/page/records-query.js +780 -0
- package/dist/core/page/render.d.ts +67 -25
- package/dist/core/page/render.js +492 -272
- package/dist/core/page/sandbox.d.ts +85 -0
- package/dist/core/page/sandbox.js +357 -0
- package/dist/core/page/time-format.d.ts +27 -0
- package/dist/core/page/time-format.js +84 -0
- package/dist/core/page/typed.d.ts +165 -159
- package/dist/core/page/workspace.d.ts +25 -1
- package/dist/core/page/workspace.js +48 -13
- package/dist/core/party/schema.d.ts +74 -3
- package/dist/core/party/schema.js +39 -6
- package/dist/core/party/types.d.ts +8 -13
- package/dist/core/sequence/define.d.ts +1 -2
- package/dist/core/slot/company-metadata.d.ts +11 -22
- package/dist/core/slot/company-metadata.js +12 -39
- package/dist/core/slot/compile-schema.js +6 -6
- package/dist/core/slot/field.d.ts +1 -2
- package/dist/core/slot/field.js +0 -2
- package/dist/core/slot/index.d.ts +3 -3
- package/dist/core/slot/index.js +3 -3
- package/dist/core/slot/naming.d.ts +1 -1
- package/dist/core/slot/naming.js +1 -1
- package/dist/core/slot/platform-fields.d.ts +4 -4
- package/dist/core/slot/platform-fields.js +5 -5
- package/dist/core/slot/schema-compat.d.ts +8 -7
- package/dist/core/slot/schema-compat.js +22 -31
- package/dist/core/slot/schema.d.ts +3 -59
- package/dist/core/slot/schema.js +0 -15
- package/dist/core/slot/types.d.ts +4 -10
- package/dist/core/slot/value.d.ts +2 -0
- package/dist/core/slot/value.js +6 -2
- package/dist/dev-overlay/protocol.d.ts +38 -5
- package/dist/fn-context/build-context.js +10 -4
- package/dist/fn-context/fake/index.d.ts +2 -0
- package/dist/fn-context/fake/index.js +5 -3
- package/dist/fn-context/fn-params.d.ts +2 -5
- package/dist/fn-context/fn-params.js +6 -9
- package/dist/fn-context/index.d.ts +1 -1
- package/dist/fn-context/make-ctx.js +5 -4
- package/dist/fn-context/rpc/case-orchestrator-tools.d.ts +11 -3
- package/dist/fn-context/rpc/case-orchestrator-tools.js +0 -1
- package/dist/fn-context/rpc/errors.d.ts +13 -0
- package/dist/fn-context/rpc/errors.js +22 -0
- package/dist/fn-context/rpc/index.d.ts +1 -1
- package/dist/fn-context/rpc/index.js +1 -1
- package/dist/fn-context/rpc/integration/index.d.ts +11 -1
- package/dist/fn-context/rpc/log.d.ts +11 -1
- package/dist/fn-context/rpc/platform.d.ts +11 -1
- package/dist/fn-context/rpc/records.d.ts +13 -6
- package/dist/fn-context/rpc/records.js +2 -4
- package/dist/fn-context/rpc/trpc-client.d.ts +42 -0
- package/dist/fn-context/rpc/trpc-client.js +151 -22
- package/dist/fn-context/rpc/trpc-init.d.ts +19 -1
- package/dist/fn-context/rpc/trpc-init.js +10 -4
- package/dist/fn-context/rpc/trpc-router-factory.d.ts +66 -8
- package/dist/fn-context/run-scope.js +1 -1
- package/dist/fn-context/types.d.ts +20 -6
- package/dist/index.d.ts +11 -12
- package/dist/index.js +5 -8
- package/dist/logger.d.ts +4 -0
- package/dist/logger.js +8 -0
- package/dist/platform.d.ts +32 -33
- package/dist/platform.js +23 -22
- package/dist/testing-compile-child.d.ts +2 -0
- package/dist/testing-compile-child.js +20 -0
- package/dist/testing.d.ts +368 -0
- package/dist/testing.js +439 -0
- package/dist/voice-service/actions.d.ts +12 -35
- package/dist/voice-service/index.d.ts +2 -0
- package/dist/voice-service/index.js +2 -0
- package/dist/voice-service/protocol.d.ts +604 -0
- package/dist/voice-service/protocol.js +67 -0
- package/dist/voice-service/types.d.ts +16 -6
- package/dist/worker.d.ts +2 -1
- package/dist/worker.js +2 -1
- package/package.json +20 -16
- package/dist/core/case-orchestrator/follow-ups.d.ts +0 -31
- package/dist/core/case-orchestrator/follow-ups.js +0 -103
- package/dist/core/case-orchestrator/tools.d.ts +0 -29
- package/dist/core/case-orchestrator/tools.js +0 -31
- package/dist/core/case-orchestrator/validate.d.ts +0 -11
- package/dist/core/case-orchestrator/validate.js +0 -63
- package/dist/core/functions/define/bind.d.ts +0 -25
- package/dist/core/functions/define/bind.js +0 -14
- package/dist/core/functions/define/case.d.ts +0 -9
- package/dist/core/functions/define/case.js +0 -13
- package/dist/core/functions/define/events.d.ts +0 -20
- package/dist/core/functions/define/events.js +0 -21
- package/dist/core/functions/define/no-case.d.ts +0 -4
- package/dist/core/functions/define/no-case.js +0 -9
- package/dist/core/functions/func-ref.d.ts +0 -25
- package/dist/core/functions/func-ref.js +0 -20
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* The page module's types bound to one sequence (15 §10.15): what `__gen/index.ts` exports as
|
|
3
|
-
* `definePage`, `field`, `
|
|
3
|
+
* `definePage`, `field`, `createRow` and `deleteRow`. Behaviour is
|
|
4
4
|
* `define.ts`'s; this file only types it.
|
|
5
5
|
*
|
|
6
6
|
* Everything starts from `PageTables`, generated per sequence into `__gen/slots.type.ts`: for each
|
|
@@ -15,15 +15,34 @@
|
|
|
15
15
|
* 18-record-search-index §4.6), `include` of lookups and ways back only, `some` / `every` / `none` on
|
|
16
16
|
* a way back (13-data-model-v1 §23.4);
|
|
17
17
|
* - an action's arguments come from its `parameters`; `db.<table>`'s writes take only that table's fields;
|
|
18
|
-
* - the page is the conversation's: code (functions, event handlers, the Orchestrator)
|
|
19
|
-
* (`
|
|
18
|
+
* - the page is the conversation's: code (functions, event handlers, the Orchestrator) is called
|
|
19
|
+
* `(ctx, args)` and reads with `ctx.api.db`.
|
|
20
20
|
*/
|
|
21
|
-
import type {
|
|
21
|
+
import type { Action, AllPrefilled, DoNode, FieldNode, FullPrefill, FunctionHandle, KeyedOf, LeftForAi, PageActionHandle, PageContent, PageNode, PageSettings, RequiredKeys, RunAction, AnyRunHandle, RunArgs, SameArgs, SayOf } from './fns.js';
|
|
22
|
+
import type { PageTime, ChooseParam, RefOption, PageBaseContext, PageChannel, PageChannelCaps, PageConversation, PageFaq, PageFaqEntry, PageHistory, PagePersona, PageRuns, PageScheduledAction, SlotState } from './define.js';
|
|
22
23
|
declare const ID_BRAND: unique symbol;
|
|
23
24
|
/** A row id of table `T`: an `Id<'injuries'>` is not an `Id<'providers'>`, and no string is an id. */
|
|
24
25
|
export type Id<T extends string = string> = string & {
|
|
25
26
|
readonly [ID_BRAND]: T;
|
|
26
27
|
};
|
|
28
|
+
declare const FORMAT_BRAND: unique symbol;
|
|
29
|
+
/**
|
|
30
|
+
* A string in a format the AI is told (38 §2.4): any string is one, and the builder reads the mark to
|
|
31
|
+
* show the parameter as `date`, `phone`…; one format is not another.
|
|
32
|
+
*/
|
|
33
|
+
type Formatted<F extends string> = string & {
|
|
34
|
+
readonly [FORMAT_BRAND]?: F;
|
|
35
|
+
};
|
|
36
|
+
/** A calendar date, `YYYY-MM-DD`: the AI sees `date`. */
|
|
37
|
+
export type IsoDate = Formatted<'date'>;
|
|
38
|
+
/** An instant, ISO 8601 with an offset or Z: the AI sees `datetime`. */
|
|
39
|
+
export type IsoDateTime = Formatted<'datetime'>;
|
|
40
|
+
/** A time of day, `HH:mm`: the AI sees `time`. */
|
|
41
|
+
export type TimeOfDay = Formatted<'time'>;
|
|
42
|
+
/** A phone number: the AI sees `phone`. */
|
|
43
|
+
export type Phone = Formatted<'phone'>;
|
|
44
|
+
/** An email address: the AI sees `email`. */
|
|
45
|
+
export type Email = Formatted<'email'>;
|
|
27
46
|
/** One field, as `__gen/slots.type.ts` describes it. */
|
|
28
47
|
export type PageFieldDesc = {
|
|
29
48
|
value: unknown;
|
|
@@ -210,9 +229,10 @@ type ScalarFilterOf<V> = V | null | {
|
|
|
210
229
|
lte?: V;
|
|
211
230
|
gt?: V;
|
|
212
231
|
gte?: V;
|
|
213
|
-
contains
|
|
232
|
+
/** A text's beginning; there is no `contains` / `endsWith`: find by a beginning or an exact field (34 §10). */
|
|
214
233
|
startsWith?: string;
|
|
215
|
-
|
|
234
|
+
/** `insensitive`: text compared in any case (`equals`, `in`, `startsWith`, ranges). */
|
|
235
|
+
mode?: 'default' | 'insensitive';
|
|
216
236
|
/** By the slot's state (`asked_unknown`, `declined`, …): the one extension to Prisma's `where`. */
|
|
217
237
|
state?: SlotState;
|
|
218
238
|
};
|
|
@@ -320,14 +340,23 @@ type SelectKey<D, T extends keyof D, S> = {
|
|
|
320
340
|
} | {
|
|
321
341
|
select: S & ExactSelect<D, T, S>;
|
|
322
342
|
};
|
|
343
|
+
/**
|
|
344
|
+
* `after`: a row of the table as read, whatever its `include` / `select` (normally the last of the page
|
|
345
|
+
* before); the rows strictly after it in the read's order come (define.ts `FindArgs.after`).
|
|
346
|
+
*/
|
|
347
|
+
type AfterRow<T> = Readonly<{
|
|
348
|
+
id: Id<T & string>;
|
|
349
|
+
createdAt?: string;
|
|
350
|
+
updatedAt?: string;
|
|
351
|
+
}> & {
|
|
352
|
+
readonly [field: string]: unknown;
|
|
353
|
+
};
|
|
323
354
|
export type FindManyArgs<D, T extends keyof D, I = IncludeArg<D, T>, S = SelectArg<D, T>> = IncludeKey<D, T, I> & SelectKey<D, T, S> & {
|
|
324
355
|
where: Where<D, T>;
|
|
325
356
|
orderBy?: OrderByArg<D, T>;
|
|
326
357
|
take?: number;
|
|
327
358
|
skip?: number;
|
|
328
|
-
|
|
329
|
-
id: Id<T & string>;
|
|
330
|
-
};
|
|
359
|
+
after?: AfterRow<T>;
|
|
331
360
|
};
|
|
332
361
|
/** `findUnique`: by `id`; null when there is no such row. */
|
|
333
362
|
export type FindUniqueArgs<D, T extends keyof D, I = IncludeArg<D, T>, S = SelectArg<D, T>> = IncludeKey<D, T, I> & SelectKey<D, T, S> & {
|
|
@@ -428,10 +457,12 @@ type TypedPageBaseContext<D, S extends string> = {
|
|
|
428
457
|
scheduledAction: PageScheduledAction | null;
|
|
429
458
|
/** The sequence's office hours now; null when it has none. */
|
|
430
459
|
officeHours: PageBaseContext['officeHours'];
|
|
431
|
-
/** The
|
|
432
|
-
|
|
460
|
+
/** The case's next step (40 §2.2): its pending contacts, soonest first; the platform shows it before the page. */
|
|
461
|
+
nextSteps: PageBaseContext['nextSteps'];
|
|
433
462
|
/** The business root's id. */
|
|
434
463
|
subject: Id<S>;
|
|
464
|
+
/** The instance this conversation is on: prefill it to a function that needs it (38 §2.2). */
|
|
465
|
+
instanceId: string;
|
|
435
466
|
/** The contact of the conversation; null outside one. */
|
|
436
467
|
caller: RowIfTable<D, 'contact'> | null;
|
|
437
468
|
/** This conversation's session row (the session fields, cells); null outside one. */
|
|
@@ -442,21 +473,10 @@ type TypedPageBaseContext<D, S extends string> = {
|
|
|
442
473
|
history: PageHistory;
|
|
443
474
|
/** ISO timestamp of this render. */
|
|
444
475
|
now: string;
|
|
445
|
-
/** A text or an email to send now (25 §8): `ctx.messages.text('link', { body })`. */
|
|
446
|
-
messages: TypedPageMessages<D>;
|
|
447
476
|
/** The contact's time zone, today there, and `format` for a time as people read it (25 §11). */
|
|
448
477
|
time: PageTime;
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
/** The contact it goes to (a contact row the page read); absent: the contact of this conversation. */
|
|
452
|
-
to?: RowIfTable<D, 'contact'> | Id<'contact'>;
|
|
453
|
-
};
|
|
454
|
-
/** `ctx.messages`, its `to` a contact of this company. */
|
|
455
|
-
export type TypedPageMessages<D> = {
|
|
456
|
-
text(key: string, options?: TypedMessageOptions<D>): MessageAction;
|
|
457
|
-
email(key: string, options?: TypedMessageOptions<D> & {
|
|
458
|
-
subject?: string;
|
|
459
|
-
}): MessageAction;
|
|
478
|
+
/** The environment's configuration, read only (76 §2.19): `ctx.env.get('callback_number')`. */
|
|
479
|
+
env: PageBaseContext['env'];
|
|
460
480
|
};
|
|
461
481
|
export type TypedActionContext<D, S extends string> = {
|
|
462
482
|
db: TypedDb<D>;
|
|
@@ -466,106 +486,41 @@ export type TypedActionContext<D, S extends string> = {
|
|
|
466
486
|
session: RowIfTable<D, 'session'> | null;
|
|
467
487
|
now: string;
|
|
468
488
|
};
|
|
469
|
-
/** `table.field` (or `table.id`, a row) of this sequence: what `schemaField` takes. */
|
|
470
|
-
export type SchemaFieldPath<D> = {
|
|
471
|
-
[T in TableOf<D>]: `${T}.id` | `${T}.${FieldOf<D, T>}`;
|
|
472
|
-
}[TableOf<D>];
|
|
473
|
-
export type TypedSchemaFieldParam<P extends string> = {
|
|
474
|
-
readonly $schemaField: P;
|
|
475
|
-
readonly extraction?: string;
|
|
476
|
-
};
|
|
477
|
-
/** One parameter: a schema field, or plain JSON Schema (an LLM function call's `parameters`). */
|
|
478
|
-
export type TypedActionParam<D> = TypedSchemaFieldParam<SchemaFieldPath<D>> | {
|
|
479
|
-
readonly type: 'string';
|
|
480
|
-
readonly description?: string;
|
|
481
|
-
readonly enum?: readonly string[];
|
|
482
|
-
} | {
|
|
483
|
-
readonly type: 'number' | 'integer';
|
|
484
|
-
readonly description?: string;
|
|
485
|
-
readonly enum?: readonly number[];
|
|
486
|
-
} | {
|
|
487
|
-
readonly type: 'boolean';
|
|
488
|
-
readonly description?: string;
|
|
489
|
-
} | {
|
|
490
|
-
readonly type: 'array';
|
|
491
|
-
readonly items: TypedActionParam<D>;
|
|
492
|
-
readonly description?: string;
|
|
493
|
-
} | {
|
|
494
|
-
readonly type: 'object';
|
|
495
|
-
readonly properties: {
|
|
496
|
-
readonly [key: string]: TypedActionParam<D>;
|
|
497
|
-
};
|
|
498
|
-
readonly required?: readonly string[];
|
|
499
|
-
readonly description?: string;
|
|
500
|
-
};
|
|
501
|
-
export type TypedActionParameters<D> = {
|
|
502
|
-
readonly type: 'object';
|
|
503
|
-
readonly properties: {
|
|
504
|
-
readonly [key: string]: TypedActionParam<D>;
|
|
505
|
-
};
|
|
506
|
-
readonly required?: readonly string[];
|
|
507
|
-
};
|
|
508
|
-
/** What `run` gets for one parameter. */
|
|
509
|
-
type ParamValue<D, P> = P extends {
|
|
510
|
-
$schemaField: `${infer T}.${infer F}`;
|
|
511
|
-
} ? T extends keyof D ? F extends 'id' ? Id<T> : ValueOf<D, T, F> : never : P extends {
|
|
512
|
-
type: 'string';
|
|
513
|
-
enum: readonly (infer E)[];
|
|
514
|
-
} ? E : P extends {
|
|
515
|
-
type: 'string';
|
|
516
|
-
} ? string : P extends {
|
|
517
|
-
type: 'number' | 'integer';
|
|
518
|
-
enum: readonly (infer E)[];
|
|
519
|
-
} ? E : P extends {
|
|
520
|
-
type: 'number' | 'integer';
|
|
521
|
-
} ? number : P extends {
|
|
522
|
-
type: 'boolean';
|
|
523
|
-
} ? boolean : P extends {
|
|
524
|
-
type: 'array';
|
|
525
|
-
items: infer I;
|
|
526
|
-
} ? Array<ParamValue<D, I>> : P extends {
|
|
527
|
-
type: 'object';
|
|
528
|
-
properties: infer Props;
|
|
529
|
-
} ? ArgsOf<D, {
|
|
530
|
-
properties: Props;
|
|
531
|
-
required: P extends {
|
|
532
|
-
required: infer R;
|
|
533
|
-
} ? R : [];
|
|
534
|
-
}> : never;
|
|
535
|
-
type RequiredOf<P> = P extends {
|
|
536
|
-
required: readonly (infer R)[];
|
|
537
|
-
} ? R : never;
|
|
538
|
-
/** What `run` gets: every parameter, required ones present, others optional. */
|
|
539
|
-
export type ArgsOf<D, P> = P extends {
|
|
540
|
-
properties: infer Props;
|
|
541
|
-
} ? Simplify<{
|
|
542
|
-
-readonly [K in Extract<keyof Props, RequiredOf<P>>]: ParamValue<D, Props[K]>;
|
|
543
|
-
} & {
|
|
544
|
-
-readonly [K in Exclude<keyof Props, RequiredOf<P>>]?: ParamValue<D, Props[K]>;
|
|
545
|
-
}> : Record<never, never>;
|
|
546
489
|
declare const CHOOSE_BRAND: unique symbol;
|
|
547
490
|
/** `choose(rows, label)` over rows of `T` (25 §10): the rows a row parameter of `T` is chosen among. */
|
|
548
491
|
export type TypedChoose<T extends string> = ChooseParam & {
|
|
549
492
|
readonly [CHOOSE_BRAND]?: T;
|
|
550
493
|
};
|
|
551
|
-
/**
|
|
494
|
+
/**
|
|
495
|
+
* What the page fixed of an action's parameters (35 §2): values, a row parameter by its row's id; an
|
|
496
|
+
* optional one also `null`, none (the AI is not asked).
|
|
497
|
+
*/
|
|
552
498
|
export type PrefillOf<A> = {
|
|
553
|
-
[K in keyof A]?: A[K] | (
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
499
|
+
[K in keyof A]?: A[K] | (undefined extends A[K] ? null : never);
|
|
500
|
+
};
|
|
501
|
+
/** The parameters of `A` that are rows. */
|
|
502
|
+
type RowKeys<A> = {
|
|
503
|
+
[K in keyof A]-?: NonNullable<A[K]> extends {
|
|
504
|
+
readonly [ID_BRAND]: string;
|
|
505
|
+
} ? K : never;
|
|
506
|
+
}[keyof A];
|
|
557
507
|
/**
|
|
558
|
-
*
|
|
559
|
-
*
|
|
560
|
-
* Placing it as it is leaves a row argument to the rows the page happens to show: not recommended.
|
|
508
|
+
* The rows the AI chooses a row parameter among, each with its label (35 §2): `choose(rows, label)`.
|
|
509
|
+
* With no row parameter there is nothing to choose: `options` takes nothing (`{}` would take anything).
|
|
561
510
|
*/
|
|
562
|
-
export type
|
|
563
|
-
|
|
511
|
+
export type OptionsOf<A> = [RowKeys<A>] extends [never] ? never : {
|
|
512
|
+
[K in RowKeys<A>]?: NonNullable<A[K]> extends {
|
|
513
|
+
readonly [ID_BRAND]: infer T extends string;
|
|
514
|
+
} ? TypedChoose<T> : never;
|
|
564
515
|
};
|
|
516
|
+
/** A page action's function (76 §2.11): `(ctx, args)`; what it is called with is the button's `prefill` and what the AI fills. */
|
|
517
|
+
export type PageActionFn<A> = (ctx: never, args: A) => unknown;
|
|
518
|
+
/** What a page function returns: `page(…)`, or `doNow(…)` to do something first (76). */
|
|
519
|
+
export type PageResult = PageNode | DoNode;
|
|
565
520
|
/** The page module of one sequence: `D` its tables (`PageTables`), `S` its business root table. */
|
|
566
521
|
export type TypedPageModule<D, S extends string> = {
|
|
567
522
|
/** Each channel's page is its own (17b §9.1): what a call shows and what a text shows may differ. */
|
|
568
|
-
definePage<Call = never, Sms = never, Email = never>(definition: {
|
|
523
|
+
definePage<Call extends PageResult = never, Sms extends PageResult = never, Email extends PageResult = never>(definition: {
|
|
569
524
|
/** Called once when the conversation starts (24 §4): the persona for `ctx.channel`. */
|
|
570
525
|
persona: (ctx: TypedPageContext<D, S>) => string | Promise<string>;
|
|
571
526
|
/** Called once when the conversation starts (24 §4): the FAQ, at most 100 entries. */
|
|
@@ -583,60 +538,111 @@ export type TypedPageModule<D, S extends string> = {
|
|
|
583
538
|
email?: (ctx: TypedPageContext<D, S, 'email'>) => Email | Promise<Email>;
|
|
584
539
|
};
|
|
585
540
|
};
|
|
586
|
-
field<Sl extends TypedSlot<unknown, string, string>>(slot: Sl, options?: FieldOptions): FieldCell<Sl>;
|
|
587
|
-
/** A ref field (26 §16.2 #7): the rows it may point at, `{ id, label }` each, or `choose(rows, label)`. */
|
|
588
|
-
refField<Sl extends TypedSlot<unknown, string, string>>(slot: Sl, options?: {
|
|
589
|
-
options?: ReadonlyArray<RefOption & {
|
|
590
|
-
id: Sl['value'] & string;
|
|
591
|
-
}> | ChooseParam;
|
|
592
|
-
readOnly?: boolean;
|
|
593
|
-
}): RefFieldCell<Sl>;
|
|
594
|
-
schemaField<const P extends SchemaFieldPath<D>>(path: P, options?: SchemaFieldOptions): TypedSchemaFieldParam<P>;
|
|
595
|
-
createRow<T extends TableOf<D>, const F extends readonly Exclude<FieldOf<D, T>, ParentOf<D, T>>[]>(table: T | {
|
|
596
|
-
readonly $table: T;
|
|
597
|
-
}, options: {
|
|
598
|
-
fields: F;
|
|
599
|
-
required?: ReadonlyArray<F[number]>;
|
|
600
|
-
label?: string;
|
|
601
|
-
description?: string;
|
|
602
|
-
}): Placeable<CreateRowAction, Partial<CreateData<D, T>>>;
|
|
603
|
-
deleteRow(row: Id<TableOf<D>> | {
|
|
604
|
-
readonly id: Id<TableOf<D>>;
|
|
605
|
-
}, options?: {
|
|
606
|
-
reason?: string;
|
|
607
|
-
label?: string;
|
|
608
|
-
description?: string;
|
|
609
|
-
}): DeleteRowAction;
|
|
610
541
|
/** The rows a row parameter is chosen among, each with what the AI sees of it (25 §10). */
|
|
611
542
|
choose<R extends {
|
|
612
543
|
readonly id: Id<TableOf<D>>;
|
|
613
544
|
}>(rows: readonly R[], label: (row: R) => string): TypedChoose<R['id'] extends {
|
|
614
545
|
readonly [ID_BRAND]: infer T extends string;
|
|
615
546
|
} ? T : never>;
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
547
|
+
};
|
|
548
|
+
type AnySlot = TypedSlot<unknown, string, string>;
|
|
549
|
+
/** What a function takes: its `args`, the second parameter of `(ctx, args)` (38 §2.1). */
|
|
550
|
+
export type FunctionParamsOf<Fn> = Fn extends (...args: infer A) => unknown ? A extends [unknown, infer P, ...unknown[]] ? P extends object ? P : Record<never, never> : Record<never, never> : Record<never, never>;
|
|
551
|
+
/** `table.field` of this sequence: how the page says to fill it (`page({ extraction })`). */
|
|
552
|
+
type FieldPathOf<D> = {
|
|
553
|
+
[T in TableOf<D>]: `${T}.${FieldOf<D, T>}`;
|
|
554
|
+
}[TableOf<D>];
|
|
555
|
+
/** `fn` of `__gen` (76 §2.15): a handle per company function, its `args` type the function's. */
|
|
556
|
+
export type FunctionHandles<F> = {
|
|
557
|
+
readonly [N in keyof F & string]: FunctionHandle<N, FunctionParamsOf<F[N]>>;
|
|
558
|
+
};
|
|
559
|
+
/**
|
|
560
|
+
* `act` of `__gen` (76 §2.11): a handle per page action of `actions.ts`, its `args` type the action's. An
|
|
561
|
+
* action takes the page action's `ctx` (`ActionCtx`): one written for another (a company function's `Ctx`)
|
|
562
|
+
* has no handle, and `run()` says so.
|
|
563
|
+
*/
|
|
564
|
+
export type ActionHandles<A, D, S extends string> = {
|
|
565
|
+
readonly [N in keyof A & string]: A[N] extends (ctx: TypedActionContext<D, S>, ...rest: never[]) => unknown ? PageActionHandle<N, FunctionParamsOf<A[N]>> : `actions.${N} takes (ctx: ActionCtx, args): the page action's ctx`;
|
|
566
|
+
};
|
|
567
|
+
/** Add a row of `T` (15 §10.6): `fields` the AI fills, `prefill` what the page fixed, `options` a ref field's rows. */
|
|
568
|
+
type CreateRowOptions<D, T extends TableOf<D>> = {
|
|
569
|
+
/** What the AI fills; a ref field is chosen in `options` instead (35 §2). */
|
|
570
|
+
fields: ReadonlyArray<Exclude<FieldOf<D, T>, ParentOf<D, T> | RowKeys<CreateData<D, T>>>>;
|
|
571
|
+
required?: ReadonlyArray<Exclude<FieldOf<D, T>, ParentOf<D, T>>>;
|
|
572
|
+
prefill?: Partial<CreateData<D, T>>;
|
|
573
|
+
/** The rows the AI chooses a ref field's row among (35 §2). */
|
|
574
|
+
options?: OptionsOf<Omit<CreateData<D, T>, ParentOf<D, T>>>;
|
|
575
|
+
};
|
|
632
576
|
/**
|
|
633
|
-
* The
|
|
634
|
-
*
|
|
577
|
+
* The fields a prefill surely fills: there, and never null, undefined or a written-out '' (76 §2.14), as
|
|
578
|
+
* the write counts them; a `string` from code counts as filled (the render refuses it when it is ''). `{ body_part: null }`, `''` or a value that may be missing fills nothing: a required field prefilled so is still nobody's.
|
|
635
579
|
*/
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
}
|
|
639
|
-
|
|
640
|
-
|
|
580
|
+
type FilledKeys<P> = {
|
|
581
|
+
[X in keyof P]-?: undefined extends P[X] ? never : null extends P[X] ? never : string extends P[X] ? X : '' extends P[X] ? never : X;
|
|
582
|
+
}[keyof P];
|
|
583
|
+
/** The page's functions bound to one sequence (76 §2.17): what `__gen/index.ts` exports. */
|
|
584
|
+
export type TypedPageFns<D, S extends string, F> = {
|
|
585
|
+
/** The page (76 §2.7): settings, then content by name. */
|
|
586
|
+
page(settings: PageSettings<{
|
|
587
|
+
readonly [K in FieldPathOf<D>]?: string;
|
|
588
|
+
}>, content: PageContent): PageNode;
|
|
589
|
+
/** A field the AI may write, or read only. A ref field is `refField()`. */
|
|
590
|
+
field(slot: AnySlot, options?: {
|
|
591
|
+
readOnly?: boolean;
|
|
592
|
+
expand?: boolean;
|
|
593
|
+
}): FieldNode;
|
|
594
|
+
/** A ref field: writable, the rows it may be set to (`options`); read-only, who its value is (`label`). */
|
|
595
|
+
refField(slot: AnySlot, options: {
|
|
596
|
+
options: ReadonlyArray<RefOption> | ChooseParam;
|
|
597
|
+
readOnly?: false;
|
|
598
|
+
} | {
|
|
599
|
+
readOnly: true;
|
|
600
|
+
label?: string;
|
|
601
|
+
}): FieldNode;
|
|
602
|
+
/** Add a row (15 §10.6). */
|
|
603
|
+
createRow<T extends TableOf<D>, const R extends ReadonlyArray<Exclude<FieldOf<D, T>, ParentOf<D, T>>> = [], P extends Partial<CreateData<D, T>> = {}, K extends string | undefined = undefined>(table: T, options: Omit<CreateRowOptions<D, T>, 'options' | 'required' | 'prefill'> & {
|
|
604
|
+
required?: R;
|
|
605
|
+
prefill?: P & {
|
|
606
|
+
readonly [X in Exclude<keyof P, keyof CreateData<D, T>>]: `${X & string} is not a field of ${T}`;
|
|
607
|
+
};
|
|
608
|
+
options?: undefined;
|
|
609
|
+
runKey?: K;
|
|
610
|
+
}): Action<'createRow', KeyedOf<K>, [Exclude<R[number], FilledKeys<P>>] extends [never] ? AllPrefilled : LeftForAi>;
|
|
611
|
+
/** With `options`, the AI chooses a ref field's row: a button's, never `doNow()`'s. */
|
|
612
|
+
createRow<T extends TableOf<D>, K extends string | undefined = undefined>(table: T, options: CreateRowOptions<D, T> & {
|
|
613
|
+
options: NonNullable<CreateRowOptions<D, T>['options']>;
|
|
614
|
+
runKey?: K;
|
|
615
|
+
}): Action<'createRow', KeyedOf<K>, LeftForAi>;
|
|
616
|
+
/**
|
|
617
|
+
* Run a company function (`fn.x`) or a page action (76 §2.15): every required parameter prefilled
|
|
618
|
+
* (what `doNow()` takes), or some left for the AI. `options` are rows of each row parameter's own table.
|
|
619
|
+
*/
|
|
620
|
+
run<H extends AnyRunHandle, K extends string | undefined = undefined>(handle: H & SameArgs<H>, options: ([RequiredKeys<RunArgs<H>>] extends [never] ? {
|
|
621
|
+
prefill?: PrefillOf<RunArgs<H>>;
|
|
622
|
+
} : {
|
|
623
|
+
prefill: FullPrefill<RunArgs<H>>;
|
|
624
|
+
}) & {
|
|
625
|
+
options?: undefined;
|
|
626
|
+
args?: undefined;
|
|
627
|
+
say?: SayOf<H>;
|
|
628
|
+
runKey?: K;
|
|
629
|
+
}): RunAction<KeyedOf<K>, AllPrefilled>;
|
|
630
|
+
run<H extends AnyRunHandle, K extends string | undefined = undefined>(handle: H & SameArgs<H>, options?: {
|
|
631
|
+
prefill?: PrefillOf<RunArgs<H>>;
|
|
632
|
+
options?: OptionsOf<RunArgs<H>>;
|
|
633
|
+
args?: {
|
|
634
|
+
[P in keyof RunArgs<H>]?: string;
|
|
635
|
+
};
|
|
636
|
+
say?: SayOf<H>;
|
|
637
|
+
runKey?: K;
|
|
638
|
+
}): RunAction<KeyedOf<K>, LeftForAi>;
|
|
639
|
+
/** Delete a row and everything under it (15 §10.6.1). */
|
|
640
|
+
deleteRow<K extends string | undefined = undefined>(row: Id<TableOf<D>> | {
|
|
641
|
+
readonly id: Id<TableOf<D>>;
|
|
642
|
+
}, options?: {
|
|
643
|
+
reason?: string;
|
|
644
|
+
runKey?: K;
|
|
645
|
+
}): Action<'deleteRow', KeyedOf<K>, AllPrefilled>;
|
|
646
|
+
};
|
|
641
647
|
export {};
|
|
642
648
|
//# sourceMappingURL=typed.d.ts.map
|
|
@@ -5,7 +5,10 @@
|
|
|
5
5
|
* always a `value` attribute; flush left.
|
|
6
6
|
*
|
|
7
7
|
* <notes><note id about value/></notes> the model's own reminders (17b §8), first, all of them
|
|
8
|
-
* <
|
|
8
|
+
* <next-step channel id name to at reason customer-quote booked-in/> the platform's, before the page
|
|
9
|
+
* (40 §2.2, 51 §2): the case's pending contacts, whatever the page
|
|
10
|
+
* shows; `value` "none" when nothing is booked
|
|
11
|
+
* <guide value/> the page's `$guide`: what to do now and how
|
|
9
12
|
* <page title description fallback> the page:
|
|
10
13
|
* <definitions> once for the page, a definition per `table.field` some field
|
|
11
14
|
* <definition for label type …/> on it shows expanded (`field(slot, { expand: true })`)
|
|
@@ -15,7 +18,10 @@
|
|
|
15
18
|
* definition is not shown (its type is); a ref's one-of: its rows
|
|
16
19
|
* <text key value/> read-only text
|
|
17
20
|
* <button id title does><arg …/></button>
|
|
21
|
+
* Now: 2026-11-11T20:05Z the platform's, the last line (76 §2.19): the time now, in UTC,
|
|
22
|
+
* to the minute; the only time the AI is given as "now"
|
|
18
23
|
*/
|
|
24
|
+
import type { PageNextStep } from './define.js';
|
|
19
25
|
import type { BlockNode, RenderedPage } from './render.js';
|
|
20
26
|
export type WorkspaceNote = {
|
|
21
27
|
id: string;
|
|
@@ -24,8 +30,26 @@ export type WorkspaceNote = {
|
|
|
24
30
|
};
|
|
25
31
|
export type WorkspaceTextOptions = {
|
|
26
32
|
notes?: readonly WorkspaceNote[];
|
|
33
|
+
/**
|
|
34
|
+
* The case's next step (40 §2.2), shown before the page whatever the page shows: the AI knows what is
|
|
35
|
+
* booked before it reads the page. Times in `timeZone` (the contact's). Left out: no conversation (nothing is shown).
|
|
36
|
+
*/
|
|
37
|
+
nextSteps?: {
|
|
38
|
+
steps: readonly PageNextStep[];
|
|
39
|
+
timeZone: string;
|
|
40
|
+
};
|
|
41
|
+
/**
|
|
42
|
+
* The time now (76 §2.19): the page's last line, `Now: 2026-11-11T20:05Z`, in UTC, never the contact's
|
|
43
|
+
* zone. Every engine that shows the AI a page gives it; left out: no such line.
|
|
44
|
+
*/
|
|
45
|
+
now?: Date;
|
|
27
46
|
};
|
|
28
47
|
export declare function workspaceText(page: RenderedPage, options?: WorkspaceTextOptions): string;
|
|
48
|
+
/** The last line of every page the AI reads (76 §2.19): the time now in UTC, to the minute (`Now: 2026-11-11T20:05Z`). */
|
|
49
|
+
export declare function nowLine(now: Date): string;
|
|
50
|
+
/** Stable, short appointment handle; the service resolves it within the authorized case, rejecting ambiguity. */
|
|
51
|
+
export declare function nextStepReference(id: string): string;
|
|
52
|
+
export declare function nextStepLines(steps: readonly PageNextStep[], timeZone: string): string[];
|
|
29
53
|
/** The block at `path` (`''`: the root). */
|
|
30
54
|
export declare function blockAt(page: RenderedPage, path: string): BlockNode | null;
|
|
31
55
|
/** What `view` shows of one thing on the page (24 §3.2): a field with its definition, a button with its arguments. */
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { formatTime } from './time-format.js';
|
|
1
2
|
export function workspaceText(page, options = {}) {
|
|
2
3
|
const out = [];
|
|
3
4
|
const notes = options.notes ?? [];
|
|
@@ -7,6 +8,8 @@ export function workspaceText(page, options = {}) {
|
|
|
7
8
|
out.push(element('note', { id: n.id, about: n.about, value: n.text }));
|
|
8
9
|
out.push('</notes>');
|
|
9
10
|
}
|
|
11
|
+
if (options.nextSteps)
|
|
12
|
+
out.push(...nextStepLines(options.nextSteps.steps, options.nextSteps.timeZone));
|
|
10
13
|
const root = page.root;
|
|
11
14
|
if (root.guide)
|
|
12
15
|
out.push(element('guide', { value: root.guide }));
|
|
@@ -29,8 +32,40 @@ export function workspaceText(page, options = {}) {
|
|
|
29
32
|
for (const child of root.children)
|
|
30
33
|
walk(page, child, defined, false, out);
|
|
31
34
|
out.push('</page>');
|
|
35
|
+
if (options.now)
|
|
36
|
+
out.push(nowLine(options.now));
|
|
32
37
|
return out.join('\n');
|
|
33
38
|
}
|
|
39
|
+
/** The last line of every page the AI reads (76 §2.19): the time now in UTC, to the minute (`Now: 2026-11-11T20:05Z`). */
|
|
40
|
+
export function nowLine(now) {
|
|
41
|
+
return `Now: ${now.toISOString().slice(0, 16)}Z`;
|
|
42
|
+
}
|
|
43
|
+
/** Stable, short appointment handle; the service resolves it within the authorized case, rejecting ambiguity. */
|
|
44
|
+
export function nextStepReference(id) {
|
|
45
|
+
return `step-${id.replaceAll('-', '').slice(0, 12)}`;
|
|
46
|
+
}
|
|
47
|
+
export function nextStepLines(steps, timeZone) {
|
|
48
|
+
if (!steps.length)
|
|
49
|
+
return [element('next-step', { value: 'none: nothing is booked to contact anyone on this case' })];
|
|
50
|
+
const when = (at) => {
|
|
51
|
+
try {
|
|
52
|
+
return formatTime(at, { timeZone });
|
|
53
|
+
}
|
|
54
|
+
catch {
|
|
55
|
+
return at;
|
|
56
|
+
}
|
|
57
|
+
};
|
|
58
|
+
return steps.map((step) => element('next-step', {
|
|
59
|
+
channel: step.channel,
|
|
60
|
+
id: nextStepReference(step.id),
|
|
61
|
+
name: step.name ?? undefined,
|
|
62
|
+
to: step.contact.name ?? step.contact.id,
|
|
63
|
+
at: when(step.at),
|
|
64
|
+
reason: step.reason ?? undefined,
|
|
65
|
+
'customer-quote': step.customerQuote ?? undefined,
|
|
66
|
+
'booked-in': step.bookedIn ? `the ${step.bookedIn.channel === 'call' ? 'call' : step.bookedIn.channel === 'sms' ? 'texts' : 'email'} of ${when(step.bookedIn.at)}` : 'by the case\'s follow-up rules',
|
|
67
|
+
}));
|
|
68
|
+
}
|
|
34
69
|
const kindOf = (cell) => `${cell.ref.table}.${cell.ref.field}`;
|
|
35
70
|
/** Each `table.field` some field on the page shows expanded, in page order: the page gives its definition once. */
|
|
36
71
|
function definedCells(page) {
|
|
@@ -51,7 +86,7 @@ function walk(page, node, defined, inList, out) {
|
|
|
51
86
|
switch (node.kind) {
|
|
52
87
|
case 'block': {
|
|
53
88
|
const tag = node.list ? 'list' : 'block';
|
|
54
|
-
out.push(open(tag, { key: inList ? undefined : node.key, title: node.title, description: node.description }));
|
|
89
|
+
out.push(open(tag, { key: inList ? undefined : node.key || undefined, title: node.title, description: node.description }));
|
|
55
90
|
for (const child of node.children)
|
|
56
91
|
walk(page, child, defined, node.list, out);
|
|
57
92
|
out.push(`</${tag}>`);
|
|
@@ -66,13 +101,18 @@ function walk(page, node, defined, inList, out) {
|
|
|
66
101
|
case 'text':
|
|
67
102
|
// null: the page put nothing here now (a region that does not apply yet, a value it has not got).
|
|
68
103
|
// In a list it has no key of its own, only its place, as a block there (26 §16.2 #10).
|
|
69
|
-
out.push(element('text', { key: inList ? undefined : node.key, value: node.value }));
|
|
104
|
+
out.push(element('text', { key: inList ? undefined : node.key || undefined, value: node.value }));
|
|
70
105
|
return;
|
|
71
106
|
case 'action':
|
|
72
107
|
out.push(...buttonLines(page.actions[node.actionId]));
|
|
73
108
|
}
|
|
74
109
|
}
|
|
75
|
-
|
|
110
|
+
/**
|
|
111
|
+
* Whether the AI may change a field (30 §3): the field's final permission, the same wherever it is on the
|
|
112
|
+
* page. A place marked read-only cannot stop the AI writing a field writable elsewhere (it writes by id),
|
|
113
|
+
* so marking it there would only contradict the other place.
|
|
114
|
+
*/
|
|
115
|
+
const editable = (_node, cell) => cell.writable;
|
|
76
116
|
/**
|
|
77
117
|
* A field's value (26 §16.2): `key` always (#10; in a list, where it has only its place, none); `readonly`
|
|
78
118
|
* only on one the AI cannot change (#6a); `more` when its definition is not shown, with its type (#6);
|
|
@@ -81,12 +121,12 @@ const editable = (node, cell) => !node.readOnly && cell.writable;
|
|
|
81
121
|
* labelled it.
|
|
82
122
|
*/
|
|
83
123
|
function fieldAttrs(page, node, cell, more, inList = false) {
|
|
84
|
-
const value = valueOf(cell
|
|
124
|
+
const value = valueOf(cell);
|
|
85
125
|
const open = editable(node, cell);
|
|
86
126
|
const labels = cell.optionLabels ?? {};
|
|
87
127
|
return {
|
|
88
128
|
id: cell.slotId,
|
|
89
|
-
key: inList ? undefined : node.key,
|
|
129
|
+
key: inList ? undefined : node.key || undefined,
|
|
90
130
|
readonly: !open,
|
|
91
131
|
more,
|
|
92
132
|
type: more ? cell.type : undefined,
|
|
@@ -97,16 +137,11 @@ function fieldAttrs(page, node, cell, more, inList = false) {
|
|
|
97
137
|
reason: (cell.state === 'asked_unknown' || cell.state === 'declined') && cell.reason ? cell.reason : undefined,
|
|
98
138
|
};
|
|
99
139
|
}
|
|
100
|
-
/** The value as JSON holds it; a
|
|
101
|
-
function valueOf(cell
|
|
140
|
+
/** The value as JSON holds it; a ref's is its row's name (33); null when not filled. */
|
|
141
|
+
function valueOf(cell) {
|
|
102
142
|
if (cell.state !== 'filled')
|
|
103
143
|
return null;
|
|
104
|
-
|
|
105
|
-
const name = Object.entries(page.rows).find(([, row]) => row.id === cell.value)?.[0];
|
|
106
|
-
if (name)
|
|
107
|
-
return name;
|
|
108
|
-
}
|
|
109
|
-
return cell.value ?? null;
|
|
144
|
+
return cell.valueRow ?? cell.value ?? null;
|
|
110
145
|
}
|
|
111
146
|
/**
|
|
112
147
|
* What a field means and takes (26 §15.3): label, type, allowed values (`one-of`; a ref field's rows are
|