Line data Source code
1 : import * as core from '@ankoh/dashql-core';
2 :
3 : import { scriptDisplayName } from './script_types.js';
4 : import { planAttachments } from '../attachments/session_attachments.js';
5 : import { orderedSessionScripts, type SessionScripts } from './session_scripts.js';
6 :
7 : /// The table parameters of every session, by session id
8 1 : const REGISTRIES = new Map<string, core.DashQLTableParameters>();
9 :
10 : /// The table parameters of a session, which the scripts and drafts of the session read
11 1 : export function sessionTableParameters(session: SessionScripts): core.DashQLTableParameters | null {
12 1 : let registry = REGISTRIES.get(session.sessionId);
13 1 : if (registry == null) {
14 : // Sessions without the core, e.g. of tests, have no table parameters
15 1 : if (typeof session.instance?.createTableParameters !== 'function') return null;
16 1 : registry = session.instance.createTableParameters();
17 1 : REGISTRIES.set(session.sessionId, registry);
18 1 : }
19 1 : return registry;
20 1 : }
21 :
22 : /// Forget the table parameters of a session
23 1 : export function dropSessionTableParameters(sessionId: string): void {
24 1 : REGISTRIES.get(sessionId)?.destroy();
25 1 : REGISTRIES.delete(sessionId);
26 1 : }
27 :
28 : /// Publish the table parameters of a session after its scripts or attachments changed. The scripts whose analysis is outdated by
29 : /// them, e.g. those that read a script whose columns changed, are marked outdated and analyzed again.
30 1 : export function publishTableParameters(prev: SessionScripts, next: SessionScripts): SessionScripts {
31 1 : if (prev.scripts === next.scripts && prev.scriptOrder === next.scriptOrder && prev.scriptRefs === next.scriptRefs
32 1 : && prev.attachments === next.attachments) {
33 1 : return next;
34 : }
35 1 : try {
36 1 : const registry = sessionTableParameters(next);
37 1 : if (registry == null) return next;
38 1 : const scripts = orderedSessionScripts(next);
39 1 : const outdated = registry.publish(
40 1 : scripts.map(script => ({ name: scriptDisplayName(script.fileName), session: script.scriptSession })),
41 1 : planAttachments(next.attachments),
42 1 : );
43 1 : if (outdated.length === 0) return next;
44 1 : const marked = { ...next.scripts };
45 1 : for (const index of outdated) {
46 1 : const script = scripts[index];
47 1 : if (script != null && !script.analysisOutdated) marked[script.scriptKey] = { ...script, analysisOutdated: true };
48 1 : }
49 1 : return { ...next, scripts: marked };
50 1 : } catch (e) {
51 1 : console.warn('cannot publish the table parameters of the session', e);
52 1 : return next;
53 1 : }
54 1 : }
|