@hydranium/cli 1.0.0-next.309 → 1.0.0-next.312
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/lib/commands/init-args.js +7 -7
- package/lib/commands/init-args.js.map +1 -1
- package/lib/commands/init-prompt.d.ts +3 -3
- package/lib/commands/init-prompt.d.ts.map +1 -1
- package/lib/commands/init-prompt.js +4 -5
- package/lib/commands/init-prompt.js.map +1 -1
- package/lib/commands/init-templates.d.ts.map +1 -1
- package/lib/commands/init-templates.js +191 -93
- package/lib/commands/init-templates.js.map +1 -1
- package/lib/commands/init-wizard.d.ts.map +1 -1
- package/lib/commands/init-wizard.js +4 -16
- package/lib/commands/init-wizard.js.map +1 -1
- package/lib/commands/init.d.ts +3 -6
- package/lib/commands/init.d.ts.map +1 -1
- package/lib/commands/init.js +3 -9
- package/lib/commands/init.js.map +1 -1
- package/package.json +10 -10
- package/src/commands/init-args.ts +7 -7
- package/src/commands/init-prompt.ts +5 -6
- package/src/commands/init-templates.ts +213 -98
- package/src/commands/init-wizard.ts +4 -16
- package/src/commands/init.ts +4 -12
- package/templates/server/src/glsp/__GRAMMAR_ID__/gmodel-factory.ts +1 -1
- package/templates/server/test/__GRAMMAR_ID__-diagram.test.ts +24 -1
|
@@ -112,8 +112,8 @@ export function parseInitArgs(args, onError = exitWithUsage) {
|
|
|
112
112
|
scoped().diagram = true;
|
|
113
113
|
break;
|
|
114
114
|
case '--heads': {
|
|
115
|
-
// Validated in `resolveInitComposition
|
|
116
|
-
//
|
|
115
|
+
// Validated in `resolveInitComposition`; the cast only gets the
|
|
116
|
+
// strings that far.
|
|
117
117
|
heads = next().split(',');
|
|
118
118
|
break;
|
|
119
119
|
}
|
|
@@ -180,11 +180,11 @@ export const INIT_HELP = [
|
|
|
180
180
|
' --name <Name> PascalCase PROJECT name; drives the services and the',
|
|
181
181
|
' Langium projectName, i.e. the shared generated symbols',
|
|
182
182
|
' (<Name>AstReflection, <Name>GeneratedSharedModule) (required).',
|
|
183
|
-
' --heads <list> Comma-separated protocol heads: lsp, data, glsp
|
|
184
|
-
'
|
|
185
|
-
'
|
|
186
|
-
' The emitted dependencies, main.ts and
|
|
187
|
-
' all follow this set. Default: lsp,data.',
|
|
183
|
+
' --heads <list> Comma-separated protocol heads: lsp, data, glsp, any',
|
|
184
|
+
' non-empty set. Without lsp, main.ts serves the socket',
|
|
185
|
+
' heads from a workspace path it is given and prints',
|
|
186
|
+
' their ports. The emitted dependencies, main.ts and',
|
|
187
|
+
' module bindings all follow this set. Default: lsp,data.',
|
|
188
188
|
' --force Scaffold into a non-empty directory anyway.',
|
|
189
189
|
' --monorepo Scaffold the packages as members of the surrounding npm',
|
|
190
190
|
' workspace, with no root of their own: each tsconfig',
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"init-args.js","sourceRoot":"","sources":["../../src/commands/init-args.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"init-args.js","sourceRoot":"","sources":["../../src/commands/init-args.ts"],"names":[],"mappings":"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"}
|
|
@@ -39,7 +39,7 @@ export interface PromptPort {
|
|
|
39
39
|
readonly choices: ReadonlyArray<PromptChoice<Value>>;
|
|
40
40
|
readonly initialValue?: Value;
|
|
41
41
|
}) => Promise<Value>;
|
|
42
|
-
/** Ask for
|
|
42
|
+
/** Ask for at least one of several choices. */
|
|
43
43
|
readonly multiselect: <Value extends string>(options: {
|
|
44
44
|
readonly message: string;
|
|
45
45
|
readonly choices: ReadonlyArray<PromptChoice<Value>>;
|
|
@@ -53,8 +53,8 @@ export interface PromptPort {
|
|
|
53
53
|
/** Close the session with a closing line. */
|
|
54
54
|
readonly outro: (message: string) => void;
|
|
55
55
|
}
|
|
56
|
-
/** The
|
|
57
|
-
export declare const
|
|
56
|
+
/** The heads, as a checkbox list. */
|
|
57
|
+
export declare const HEAD_CHOICES: ReadonlyArray<PromptChoice<InitHead>>;
|
|
58
58
|
/**
|
|
59
59
|
* The real prompt, backed by `@clack/prompts`.
|
|
60
60
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"init-prompt.d.ts","sourceRoot":"","sources":["../../src/commands/init-prompt.ts"],"names":[],"mappings":"AAAA;;;;;;;kFAOkF;AAqBlF,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AAE1C,wFAAwF;AACxF,MAAM,WAAW,YAAY,CAAC,KAAK,SAAS,MAAM;IAC/C,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAC;IACtB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,2EAA2E;IAC3E,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;CACzB;AAED,mGAAmG;AACnG,MAAM,WAAW,iBAAiB;IAC/B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,MAAM,GAAG,SAAS,CAAC;CAC5D;AAED,4EAA4E;AAC5E,qBAAa,mBAAoB,SAAQ,KAAK;IAC3C,cAGC;CACH;AAED,sDAAsD;AACtD,MAAM,WAAW,UAAU;IACxB,qCAAqC;IACrC,QAAQ,CAAC,KAAK,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IACxC,sDAAsD;IACtD,QAAQ,CAAC,IAAI,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,KAAK,IAAI,CAAC;IACzD,8BAA8B;IAC9B,QAAQ,CAAC,IAAI,EAAE,CAAC,OAAO,EAAE,iBAAiB,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;IAC/D,8CAA8C;IAC9C,QAAQ,CAAC,MAAM,EAAE,CAAC,KAAK,SAAS,MAAM,EAAE,OAAO,EAAE;QAC9C,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;QACzB,QAAQ,CAAC,OAAO,EAAE,aAAa,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC,CAAC;QACrD,QAAQ,CAAC,YAAY,CAAC,EAAE,KAAK,CAAC;KAChC,KAAK,OAAO,CAAC,KAAK,CAAC,CAAC;IACrB
|
|
1
|
+
{"version":3,"file":"init-prompt.d.ts","sourceRoot":"","sources":["../../src/commands/init-prompt.ts"],"names":[],"mappings":"AAAA;;;;;;;kFAOkF;AAqBlF,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AAE1C,wFAAwF;AACxF,MAAM,WAAW,YAAY,CAAC,KAAK,SAAS,MAAM;IAC/C,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAC;IACtB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,2EAA2E;IAC3E,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;CACzB;AAED,mGAAmG;AACnG,MAAM,WAAW,iBAAiB;IAC/B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,MAAM,GAAG,SAAS,CAAC;CAC5D;AAED,4EAA4E;AAC5E,qBAAa,mBAAoB,SAAQ,KAAK;IAC3C,cAGC;CACH;AAED,sDAAsD;AACtD,MAAM,WAAW,UAAU;IACxB,qCAAqC;IACrC,QAAQ,CAAC,KAAK,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IACxC,sDAAsD;IACtD,QAAQ,CAAC,IAAI,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,KAAK,IAAI,CAAC;IACzD,8BAA8B;IAC9B,QAAQ,CAAC,IAAI,EAAE,CAAC,OAAO,EAAE,iBAAiB,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;IAC/D,8CAA8C;IAC9C,QAAQ,CAAC,MAAM,EAAE,CAAC,KAAK,SAAS,MAAM,EAAE,OAAO,EAAE;QAC9C,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;QACzB,QAAQ,CAAC,OAAO,EAAE,aAAa,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC,CAAC;QACrD,QAAQ,CAAC,YAAY,CAAC,EAAE,KAAK,CAAC;KAChC,KAAK,OAAO,CAAC,KAAK,CAAC,CAAC;IACrB,+CAA+C;IAC/C,QAAQ,CAAC,WAAW,EAAE,CAAC,KAAK,SAAS,MAAM,EAAE,OAAO,EAAE;QACnD,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;QACzB,QAAQ,CAAC,OAAO,EAAE,aAAa,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC,CAAC;QACrD,QAAQ,CAAC,aAAa,CAAC,EAAE,SAAS,KAAK,EAAE,CAAC;KAC5C,KAAK,OAAO,CAAC,KAAK,EAAE,CAAC,CAAC;IACvB,6BAA6B;IAC7B,QAAQ,CAAC,OAAO,EAAE,CAAC,OAAO,EAAE;QAAE,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,YAAY,CAAC,EAAE,OAAO,CAAA;KAAE,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;IAC/G,6CAA6C;IAC7C,QAAQ,CAAC,KAAK,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;CAC5C;AAED,qCAAqC;AACrC,eAAO,MAAM,YAAY,EAAE,aAAa,CAAC,YAAY,CAAC,QAAQ,CAAC,CAI9D,CAAC;AAEF;;;;;;GAMG;AACH,wBAAsB,iBAAiB,IAAI,OAAO,CAAC,UAAU,CAAC,CAqD7D"}
|
|
@@ -13,8 +13,9 @@ export class InitWizardCancelled extends Error {
|
|
|
13
13
|
this.name = 'InitWizardCancelled';
|
|
14
14
|
}
|
|
15
15
|
}
|
|
16
|
-
/** The
|
|
17
|
-
export const
|
|
16
|
+
/** The heads, as a checkbox list. */
|
|
17
|
+
export const HEAD_CHOICES = [
|
|
18
|
+
{ value: 'lsp', label: 'lsp', hint: 'text editing in an LSP client' },
|
|
18
19
|
{ value: 'data', label: 'data', hint: 'typed JSON-RPC for forms, trees and code-gen' },
|
|
19
20
|
{ value: 'glsp', label: 'glsp', hint: 'graphical editing; adds a scaffolded diagram' }
|
|
20
21
|
];
|
|
@@ -60,9 +61,7 @@ export async function createClackPrompt() {
|
|
|
60
61
|
message: options.message,
|
|
61
62
|
options: toOptions(options.choices),
|
|
62
63
|
initialValues: options.initialValues ? [...options.initialValues] : [],
|
|
63
|
-
|
|
64
|
-
// server, so an empty selection must not be rejected.
|
|
65
|
-
required: false
|
|
64
|
+
required: true
|
|
66
65
|
})),
|
|
67
66
|
confirm: async (options) => unwrap(await clack.confirm({ message: options.message, initialValue: options.initialValue })),
|
|
68
67
|
outro: message => clack.outro(message)
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"init-prompt.js","sourceRoot":"","sources":["../../src/commands/init-prompt.ts"],"names":[],"mappings":"AAAA;;;;;;;kFAOkF;AAuClF,4EAA4E;AAC5E,MAAM,OAAO,mBAAoB,SAAQ,KAAK;IAC3C;QACG,KAAK,CAAC,wBAAwB,CAAC,CAAC;QAChC,IAAI,CAAC,IAAI,GAAG,qBAAqB,CAAC;IACrC,CAAC;CACH;AA4BD,
|
|
1
|
+
{"version":3,"file":"init-prompt.js","sourceRoot":"","sources":["../../src/commands/init-prompt.ts"],"names":[],"mappings":"AAAA;;;;;;;kFAOkF;AAuClF,4EAA4E;AAC5E,MAAM,OAAO,mBAAoB,SAAQ,KAAK;IAC3C;QACG,KAAK,CAAC,wBAAwB,CAAC,CAAC;QAChC,IAAI,CAAC,IAAI,GAAG,qBAAqB,CAAC;IACrC,CAAC;CACH;AA4BD,qCAAqC;AACrC,MAAM,CAAC,MAAM,YAAY,GAA0C;IAChE,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,+BAA+B,EAAE;IACrE,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,8CAA8C,EAAE;IACtF,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,8CAA8C,EAAE;CACxF,CAAC;AAEF;;;;;;GAMG;AACH,MAAM,CAAC,KAAK,UAAU,iBAAiB;IACpC,MAAM,KAAK,GAAG,MAAM,MAAM,CAAC,gBAAgB,CAAC,CAAC;IAE7C,uEAAuE;IACvE,MAAM,MAAM,GAAG,CAAQ,MAAsB,EAAS,EAAE;QACrD,IAAI,KAAK,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC;YAC1B,MAAM,IAAI,mBAAmB,EAAE,CAAC;QACnC,CAAC;QACD,OAAO,MAAM,CAAC;IACjB,CAAC,CAAC;IAEF,6EAA6E;IAC7E,0EAA0E;IAC1E,2EAA2E;IAC3E,MAAM,SAAS,GAAG,CAAuB,OAA2C,EAA6B,EAAE,CAChH,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;QACpB,KAAK,EAAE,MAAM,CAAC,KAAK;QACnB,KAAK,EAAE,MAAM,CAAC,KAAK;QACnB,GAAG,CAAC,MAAM,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,CAAC,IAAI,EAAE,CAAC;KAC7D,CAAC,CAA8B,CAAC;IAEpC,OAAO;QACJ,KAAK,EAAE,KAAK,CAAC,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,KAAK,CAAC;QAClC,IAAI,EAAE,CAAC,OAAO,EAAE,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,EAAE,KAAK,CAAC;QACpD,IAAI,EAAE,KAAK,EAAC,OAAO,EAAC,EAAE,CACnB,MAAM,CACH,MAAM,KAAK,CAAC,IAAI,CAAC;YACd,OAAO,EAAE,OAAO,CAAC,OAAO;YACxB,YAAY,EAAE,OAAO,CAAC,YAAY;YAClC,WAAW,EAAE,OAAO,CAAC,WAAW;YAChC,QAAQ,EAAE,KAAK,CAAC,EAAE,CAAC,OAAO,CAAC,QAAQ,EAAE,CAAC,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;SAC7D,CAAC,CACJ,CAAC,IAAI,EAAE;QACX,MAAM,EAAE,KAAK,EAAC,OAAO,EAAC,EAAE,CACrB,MAAM,CACH,MAAM,KAAK,CAAC,MAAM,CAAC;YAChB,OAAO,EAAE,OAAO,CAAC,OAAO;YACxB,OAAO,EAAE,SAAS,CAAC,OAAO,CAAC,OAAO,CAAC;YACnC,YAAY,EAAE,OAAO,CAAC,YAAY;SACpC,CAAC,CACJ;QACJ,WAAW,EAAE,KAAK,EAAC,OAAO,EAAC,EAAE,CAC1B,MAAM,CACH,MAAM,KAAK,CAAC,WAAW,CAAC;YACrB,OAAO,EAAE,OAAO,CAAC,OAAO;YACxB,OAAO,EAAE,SAAS,CAAC,OAAO,CAAC,OAAO,CAAC;YACnC,aAAa,EAAE,OAAO,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,EAAE;YACtE,QAAQ,EAAE,IAAI;SAChB,CAAC,CACJ;QACJ,OAAO,EAAE,KAAK,EAAC,OAAO,EAAC,EAAE,CAAC,MAAM,CAAC,MAAM,KAAK,CAAC,OAAO,CAAC,EAAE,OAAO,EAAE,OAAO,CAAC,OAAO,EAAE,YAAY,EAAE,OAAO,CAAC,YAAY,EAAE,CAAC,CAAC;QACvH,KAAK,EAAE,OAAO,CAAC,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,OAAO,CAAC;KACxC,CAAC;AACL,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"init-templates.d.ts","sourceRoot":"","sources":["../../src/commands/init-templates.ts"],"names":[],"mappings":"AAAA;;;;;;;kFAOkF;AAmFlF,OAAO,KAAK,EAAE,eAAe,EAAE,QAAQ,EAAoB,QAAQ,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AAGnG,qFAAqF;AACrF,MAAM,WAAW,YAAY;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;CAClB;AAED;;;;;;;;GAQG;AACH,wBAAgB,oBAAoB,IAAI,MAAM,CAE7C;AAmBD;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAAC,WAAW,EAAE,eAAe,EAAE,MAAM,EAAE,UAAU,GAAG,MAAM,CAI1F;
|
|
1
|
+
{"version":3,"file":"init-templates.d.ts","sourceRoot":"","sources":["../../src/commands/init-templates.ts"],"names":[],"mappings":"AAAA;;;;;;;kFAOkF;AAmFlF,OAAO,KAAK,EAAE,eAAe,EAAE,QAAQ,EAAoB,QAAQ,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AAGnG,qFAAqF;AACrF,MAAM,WAAW,YAAY;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;CAClB;AAED;;;;;;;;GAQG;AACH,wBAAgB,oBAAoB,IAAI,MAAM,CAE7C;AAmBD;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAAC,WAAW,EAAE,eAAe,EAAE,MAAM,EAAE,UAAU,GAAG,MAAM,CAI1F;AAgMD;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,SAAS,QAAQ,EAAE,GAAG,aAAa,CAAC,SAAS,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAUtG;AAiwDD;;;;GAIG;AACH,wBAAgB,kBAAkB,CAAC,WAAW,EAAE,eAAe,GAAG,QAAQ,EAAE,CAO3E"}
|
|
@@ -236,9 +236,13 @@ function arrayLiteral(elements, indent, columns) {
|
|
|
236
236
|
* The FRAMEWORK packages each head adds, carrying no version: every
|
|
237
237
|
* `@hydranium/*` pin is derived at scaffold time from {@link frameworkPin}, so
|
|
238
238
|
* none of them can name a version its siblings were not published at.
|
|
239
|
+
*
|
|
240
|
+
* `base` is every head set's: the services every head serves from are composed
|
|
241
|
+
* the same with or without an LSP head.
|
|
239
242
|
*/
|
|
240
243
|
const HEAD_FRAMEWORK_DEPENDENCIES = {
|
|
241
|
-
|
|
244
|
+
base: ['@hydranium/core', '@hydranium/langium', '@hydranium/protocol'],
|
|
245
|
+
lsp: [],
|
|
242
246
|
data: ['@hydranium/data-server'],
|
|
243
247
|
glsp: ['@hydranium/glsp-server']
|
|
244
248
|
};
|
|
@@ -258,12 +262,13 @@ const HEAD_FRAMEWORK_DEPENDENCIES = {
|
|
|
258
262
|
* `overrides` block exists to prevent — so a repo gate holds each entry here
|
|
259
263
|
* against the manifest that declares it.
|
|
260
264
|
*
|
|
261
|
-
* `langium` is required
|
|
265
|
+
* `langium` is required even though hand-written code goes through the
|
|
262
266
|
* `@hydranium/langium` chokepoint, because `langium-cli` emits direct imports
|
|
263
|
-
* into the generated files and regenerates them on every build.
|
|
267
|
+
* into the generated files and regenerates them on every build. The `vscode-*`
|
|
268
|
+
* packages are required peers of `@hydranium/core`, so they are `base` too.
|
|
264
269
|
*/
|
|
265
270
|
const HEAD_THIRD_PARTY_DEPENDENCIES = {
|
|
266
|
-
|
|
271
|
+
base: {
|
|
267
272
|
langium: '4.3.1',
|
|
268
273
|
// Exact, as are the protocol and transport it pins, so Langium and the
|
|
269
274
|
// framework share their copies; across copies, an error a handler throws
|
|
@@ -272,6 +277,7 @@ const HEAD_THIRD_PARTY_DEPENDENCIES = {
|
|
|
272
277
|
'vscode-jsonrpc': '9.0.0',
|
|
273
278
|
'vscode-languageserver-protocol': '3.18.1'
|
|
274
279
|
},
|
|
280
|
+
lsp: {},
|
|
275
281
|
data: {},
|
|
276
282
|
glsp: {
|
|
277
283
|
'@eclipse-glsp/graph': '2.7.0',
|
|
@@ -299,8 +305,13 @@ const PROTOCOL_THIRD_PARTY_DEPENDENCIES = {
|
|
|
299
305
|
* package shares with the framework.
|
|
300
306
|
*/
|
|
301
307
|
export function workspaceRootPins(heads) {
|
|
302
|
-
return
|
|
303
|
-
|
|
308
|
+
return [
|
|
309
|
+
...Object.entries(HEAD_THIRD_PARTY_DEPENDENCIES.base),
|
|
310
|
+
...heads.flatMap(head => [
|
|
311
|
+
...Object.entries(HEAD_THIRD_PARTY_DEPENDENCIES[head]),
|
|
312
|
+
...Object.entries(PROTOCOL_THIRD_PARTY_DEPENDENCIES[head])
|
|
313
|
+
])
|
|
314
|
+
]
|
|
304
315
|
.filter(([, version]) => /^\d+\.\d+\.\d+$/.test(version))
|
|
305
316
|
.sort(([left], [right]) => left.localeCompare(right));
|
|
306
317
|
}
|
|
@@ -334,10 +345,10 @@ function sortedBlock(dependencies, indent) {
|
|
|
334
345
|
.map(name => `${indent}"${name}": "${dependencies[name]}"`)
|
|
335
346
|
.join(',\n');
|
|
336
347
|
}
|
|
337
|
-
/** The server's dependency block: the head set's packages and the protocol member. */
|
|
348
|
+
/** The server's dependency block: the base and head set's packages and the protocol member. */
|
|
338
349
|
function dependencyBlock(composition, indent) {
|
|
339
350
|
const merged = { [memberPackageName(composition, 'protocol')]: MEMBER_PIN };
|
|
340
|
-
for (const head of composition.heads) {
|
|
351
|
+
for (const head of ['base', ...composition.heads]) {
|
|
341
352
|
Object.assign(merged, HEAD_THIRD_PARTY_DEPENDENCIES[head]);
|
|
342
353
|
for (const framework of HEAD_FRAMEWORK_DEPENDENCIES[head]) {
|
|
343
354
|
merged[framework] = frameworkPin(composition);
|
|
@@ -417,7 +428,7 @@ __BIN__ },
|
|
|
417
428
|
"generate:transfer-model": "hydranium-cli generate-transfer-model --ast-file src/language-server/generated/ast.ts --augmentation-file src/language-server/ast.ts --out-file ../protocol/src/generated-hydranium/transfer-model.ts --ast-builder-file src/language-server/generated-hydranium/ast-builder.ts --languages-file ../protocol/src/generated-hydranium/languages.ts --element-type-name __NAME__Element --terminals-name __NAME__Terminals --regen-command \\"Run: __NPM_RUN__ generate:transfer-model\\"",
|
|
418
429
|
"langium:generate": "langium generate",
|
|
419
430
|
"langium:watch": "langium generate --watch",
|
|
420
|
-
__LINT__ "start": "node lib/main.
|
|
431
|
+
__LINT__ "start": "node lib/main.js__START_ARGS__",
|
|
421
432
|
"test": "npm run typecheck:test && vitest run",
|
|
422
433
|
"typecheck:test": "tsc --noEmit -p tsconfig.test.json",
|
|
423
434
|
"watch": "tsc -b --watch"
|
|
@@ -497,6 +508,7 @@ function packageJson(composition) {
|
|
|
497
508
|
.replace('__KEYWORDS__', keywords)
|
|
498
509
|
.replace('__BIN__', binBlock(composition))
|
|
499
510
|
.replace('__LINT__', lintScript(forMember(composition, 'server'), 'src test'))
|
|
511
|
+
.replace('__START_ARGS__', composition.heads.includes('lsp') ? ' --stdio' : ' ../workspace')
|
|
500
512
|
.replace('__VITEST__', pinsVitest(composition) ? '~4.0.18' : '^4.0.0')
|
|
501
513
|
.replace('__PRIVATE__', composition.packaging.private ? ' "private": true,\n' : '')
|
|
502
514
|
.replace('__NPM_RUN__', npmRun(composition, 'server'))
|
|
@@ -810,53 +822,64 @@ ${returnType}
|
|
|
810
822
|
return project(text, composition);
|
|
811
823
|
}
|
|
812
824
|
/**
|
|
813
|
-
*
|
|
814
|
-
*
|
|
825
|
+
* How a host finds each socket head's port, in emission order: an LSP request
|
|
826
|
+
* when the LSP head publishes the ports, else the environment variable
|
|
827
|
+
* `main.ts` reads a port from.
|
|
828
|
+
*
|
|
829
|
+
* Keyed by the PROJECT rather than by a language: one server of each kind per
|
|
815
830
|
* process serves every registered grammar, so a language-derived name would tie
|
|
816
831
|
* a project-level endpoint to whichever grammar was scaffolded first.
|
|
817
832
|
*/
|
|
818
|
-
function
|
|
833
|
+
function headPortConstants(composition) {
|
|
819
834
|
const upper = screamingSnake(composition.projectId);
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
...(composition.heads.includes('
|
|
835
|
+
const lsp = composition.heads.includes('lsp');
|
|
836
|
+
const heads = [
|
|
837
|
+
...(composition.heads.includes('data') ? [{ key: 'DATA_SERVER', path: 'data-server', label: 'data-server' }] : []),
|
|
838
|
+
...(composition.heads.includes('glsp') ? [{ key: 'GLSP_SERVER', path: 'glsp-server', label: 'GLSP' }] : [])
|
|
823
839
|
];
|
|
840
|
+
return heads.map(head => lsp
|
|
841
|
+
? {
|
|
842
|
+
name: `${upper}_${head.key}_PORT_COMMAND`,
|
|
843
|
+
value: `${composition.projectId}/${head.path}/port`,
|
|
844
|
+
doc: `LSP request the host queries to discover the ${head.label} socket port.`
|
|
845
|
+
}
|
|
846
|
+
: {
|
|
847
|
+
name: `${upper}_${head.key}_PORT_ENV`,
|
|
848
|
+
value: `${upper}_${head.key}_PORT`,
|
|
849
|
+
doc: `Environment variable naming the ${head.label} socket port when no \`--${head.path}-port\` flag does.`
|
|
850
|
+
});
|
|
824
851
|
}
|
|
825
852
|
/**
|
|
826
|
-
* The socket heads'
|
|
853
|
+
* The socket heads' port commands or variables, in the protocol member.
|
|
827
854
|
*
|
|
828
|
-
* A host shell has to name the same string the server
|
|
829
|
-
*
|
|
855
|
+
* A host shell has to name the same string the server reads, and reaches it
|
|
856
|
+
* here without depending on the server. A host that retypes the literal
|
|
830
857
|
* instead gets no error when it drifts: the framework's port poll defaults to
|
|
831
858
|
* `findPortAttempts = -1`, so a wrong command retries forever rather than
|
|
832
|
-
* failing.
|
|
859
|
+
* failing, and a wrong variable is never read.
|
|
833
860
|
*/
|
|
834
861
|
function headPortsFile(composition) {
|
|
835
|
-
const
|
|
836
|
-
const
|
|
837
|
-
const
|
|
838
|
-
const
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
return `// The LSP requests a host queries to discover this server's socket head${blocks.length > 1 ? 's' : ''}.
|
|
862
|
+
const constants = headPortConstants(composition);
|
|
863
|
+
const blocks = constants.map(constant => `/** ${constant.doc} */\nexport const ${constant.name} = '${constant.value}';`);
|
|
864
|
+
const heads = `socket head${blocks.length > 1 ? 's' : ''}`;
|
|
865
|
+
const opening = composition.heads.includes('lsp')
|
|
866
|
+
? `// The LSP requests a host queries to discover this server's ${heads}.`
|
|
867
|
+
: `// The environment variables that name the ports of this server's ${heads}.`;
|
|
868
|
+
const usage = composition.heads.includes('lsp')
|
|
869
|
+
? `// The server publishes them and a host shell has to name the same string to
|
|
870
|
+
// reach the head; both import them from here. A shell that retypes the literal
|
|
871
|
+
// gets no error when it drifts: the framework's port poll retries indefinitely
|
|
872
|
+
// by default.`
|
|
873
|
+
: `// The server reads them and a process that starts it sets them; both import
|
|
874
|
+
// them from here. A variable retyped with a typo is never read, and the head
|
|
875
|
+
// then listens on whichever port is free.`;
|
|
876
|
+
return `${opening}
|
|
851
877
|
//
|
|
852
|
-
// Both are keyed by the PROJECT, not the language: one server of each kind per
|
|
878
|
+
// ${blocks.length > 1 ? 'Both are' : 'It is'} keyed by the PROJECT, not the language: one server of each kind per
|
|
853
879
|
// process serves every registered grammar, so a language-derived name would tie
|
|
854
880
|
// a project-level endpoint to whichever grammar was scaffolded first.
|
|
855
881
|
//
|
|
856
|
-
|
|
857
|
-
// reach the head; both import them from here. A shell that retypes the literal
|
|
858
|
-
// gets no error when it drifts: the framework's port poll retries indefinitely
|
|
859
|
-
// by default.
|
|
882
|
+
${usage}
|
|
860
883
|
|
|
861
884
|
${blocks.join('\n\n')}
|
|
862
885
|
`;
|
|
@@ -908,10 +931,12 @@ function mainFile(composition) {
|
|
|
908
931
|
const columns = columnsFor(composition);
|
|
909
932
|
const roots = [...composition.grammars.map(grammar => grammar.entryRule)].sort();
|
|
910
933
|
const upper = screamingSnake(composition.projectId);
|
|
934
|
+
const lsp = composition.heads.includes('lsp');
|
|
911
935
|
const data = composition.heads.includes('data');
|
|
912
936
|
const glsp = composition.heads.includes('glsp');
|
|
913
937
|
const diagrams = composition.grammars.filter(grammar => grammar.diagram);
|
|
914
938
|
const plural = roots.length > 1 ? 's' : '';
|
|
939
|
+
const portFlags = [...(data ? ['--data-server-port'] : []), ...(glsp ? ['--glsp-server-port'] : [])];
|
|
915
940
|
const headNames = composition.heads.map(head => head === 'lsp' ? 'the Langium LSP head' : head === 'data' ? 'a socket data-server (model server) head' : 'a GLSP head');
|
|
916
941
|
// Comma-joined but for the last, which takes `and`: a bare `, ` join reads as
|
|
917
942
|
// a truncated list, and the emitted comment is the first thing an adopter
|
|
@@ -920,7 +945,7 @@ function mainFile(composition) {
|
|
|
920
945
|
// `reflect-metadata` must be imported before anything that reads a
|
|
921
946
|
// decorator's emitted metadata, which inversify does at module scope.
|
|
922
947
|
const reflectImport = glsp ? "import 'reflect-metadata';\n" : '';
|
|
923
|
-
const coreNodeSymbols = ['NodeFileSystem', ...(data ? ['publishPortOnLspConnection', 'startSocketServer'] : [])];
|
|
948
|
+
const coreNodeSymbols = ['NodeFileSystem', ...(data ? [...(lsp ? ['publishPortOnLspConnection'] : []), 'startSocketServer'] : [])];
|
|
924
949
|
const glspImports = glsp
|
|
925
950
|
? `import { ServerModule } from '@eclipse-glsp/server/node.js';
|
|
926
951
|
import { GlspClientLogger, HydraniumGlspAppModule } from '@hydranium/glsp-server';
|
|
@@ -940,21 +965,32 @@ import { startGlspServer } from '@hydranium/glsp-server/node';
|
|
|
940
965
|
${importList(roots, memberPackageName(composition, 'protocol'), columns, true)}
|
|
941
966
|
`
|
|
942
967
|
: '';
|
|
943
|
-
// The
|
|
944
|
-
//
|
|
945
|
-
//
|
|
946
|
-
const
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
|
|
968
|
+
// The names live in the protocol member, not here: a host shell has to name
|
|
969
|
+
// the same string to reach the head, and this file is an executable entry,
|
|
970
|
+
// so nothing can import from it.
|
|
971
|
+
const portNames = headPortConstants(composition).map(constant => constant.name);
|
|
972
|
+
const portImports = portNames.length ? importList(portNames, memberPackageName(composition, 'protocol'), columns) + '\n' : '';
|
|
973
|
+
const dataBlock = !data
|
|
974
|
+
? ''
|
|
975
|
+
: !lsp
|
|
976
|
+
? `
|
|
977
|
+
// Data-server head: each accepted client gets its own DataServer.
|
|
978
|
+
const dataServer = startSocketServer(
|
|
979
|
+
{ shared, workspace, port: portFrom('data-server-port', ${upper}_DATA_SERVER_PORT_ENV), logTag: 'ModelServer', logger: shared.Logger },
|
|
980
|
+
dataConnection => {
|
|
981
|
+
new DataServer<${roots.join(' | ')}>(dataConnection, shared);
|
|
982
|
+
return { dispose: () => undefined };
|
|
983
|
+
}
|
|
984
|
+
);
|
|
985
|
+
`
|
|
986
|
+
: `
|
|
951
987
|
// Data-server head alongside LSP: binds an ephemeral port, published over the LSP
|
|
952
988
|
// connection for the host to discover. Each accepted client gets its own DataServer.
|
|
953
989
|
//
|
|
954
990
|
// Neither the bind nor the publish may be swallowed: either failure leaves the LSP
|
|
955
991
|
// head serving text edits while every data client waits on a port command that was
|
|
956
992
|
// never registered, and the launcher reports a bind failure only if given a logger.
|
|
957
|
-
const dataServer = startSocketServer({ port: 0, logTag: 'ModelServer', logger: shared.Logger }, dataConnection => {
|
|
993
|
+
const dataServer = startSocketServer({ shared, port: 0, logTag: 'ModelServer', logger: shared.Logger }, dataConnection => {
|
|
958
994
|
new DataServer<${roots.join(' | ')}>(dataConnection, shared);
|
|
959
995
|
return { dispose: () => undefined };
|
|
960
996
|
});
|
|
@@ -976,8 +1012,7 @@ dataServer.started
|
|
|
976
1012
|
.catch((error: unknown) => {
|
|
977
1013
|
shared.Logger.error(\`[ModelServer] Could not publish the data-server port: \${describeErrorWithStack(error)}\`);
|
|
978
1014
|
});
|
|
979
|
-
|
|
980
|
-
: '';
|
|
1015
|
+
`;
|
|
981
1016
|
const glspBlock = glsp
|
|
982
1017
|
? `
|
|
983
1018
|
// GLSP head on the same shared workspace. \`HydraniumGlspAppModule\` is used
|
|
@@ -985,39 +1020,30 @@ dataServer.started
|
|
|
985
1020
|
// grammar a request concerns, so nothing per-language belongs there — each
|
|
986
1021
|
// diagram module declares its own language instead.
|
|
987
1022
|
//
|
|
988
|
-
|
|
989
|
-
|
|
1023
|
+
${lsp
|
|
1024
|
+
? `// GLSP framework logs route through the LSP connection rather than stdout, which
|
|
1025
|
+
// IS the LSP transport in stdio mode; writing there corrupts the protocol stream.`
|
|
1026
|
+
: `// GLSP framework logs route through the framework's logger to stderr. GLSP's
|
|
1027
|
+
// own startup line goes to stdout, beside the ports line below.`}
|
|
990
1028
|
const glspServer = startGlspServer({
|
|
991
1029
|
// The GLSP log threshold lives on the logger, not beside it: the framework
|
|
992
1030
|
// replaces GLSP's own \`Logger\` binding, so a launcher-level \`logLevel\` would
|
|
993
1031
|
// be discarded. The logger tracks the framework's process-wide threshold, so
|
|
994
|
-
// \`HYDRANIUM_LOG_LEVEL\` and the LSP log-level setting govern GLSP output too;
|
|
1032
|
+
// \`HYDRANIUM_LOG_LEVEL\` ${lsp ? 'and the LSP log-level setting govern' : 'governs'} GLSP output too;
|
|
995
1033
|
// pass \`logLevel\` only to make GLSP quieter than the rest of the server.
|
|
996
1034
|
createLogger: caller => new GlspClientLogger(shared, { component: caller }),
|
|
997
1035
|
serverModule: new ServerModule()${diagrams.map(grammar => `.configureDiagramModule(new ${grammar.grammar}DiagramModule())`).join('')},
|
|
998
1036
|
appModules: [new HydraniumGlspAppModule({ shared })],
|
|
999
|
-
|
|
1000
|
-
|
|
1037
|
+
${lsp
|
|
1038
|
+
? ` lspConnection: shared.lsp.Connection,
|
|
1039
|
+
portCommand: ${upper}_GLSP_SERVER_PORT_COMMAND`
|
|
1040
|
+
: ` workspace,
|
|
1041
|
+
port: portFrom('glsp-server-port', ${upper}_GLSP_SERVER_PORT_ENV),
|
|
1042
|
+
logger: shared.Logger`}
|
|
1001
1043
|
});
|
|
1002
|
-
void glspServer
|
|
1003
|
-
`
|
|
1044
|
+
${lsp ? 'void glspServer;\n' : ''}`
|
|
1004
1045
|
: '';
|
|
1005
|
-
const
|
|
1006
|
-
// process, so every head shares one model store.
|
|
1007
|
-
// Invocation: \`node lib/main.js --stdio\`, or the package's \`__PROJECT_ID__\` bin
|
|
1008
|
-
// script.${data
|
|
1009
|
-
? `
|
|
1010
|
-
//
|
|
1011
|
-
// NOT the entry the data-server subcommands of \`hydranium-cli\` speak to: stdio
|
|
1012
|
-
// here carries LSP, and the data head is a socket whose port is published over
|
|
1013
|
-
// the LSP connection. Those subcommands spawn \`data-server-main.js\`.`
|
|
1014
|
-
: ''}
|
|
1015
|
-
//
|
|
1016
|
-
// Everything here runs at module scope, so this file is an executable rather
|
|
1017
|
-
// than a library entry — import \`./index.js\` instead to compose the language.
|
|
1018
|
-
|
|
1019
|
-
${reflectImport}${glspImports}${importList(coreNodeSymbols, '@hydranium/core/node', columns)}
|
|
1020
|
-
${data ? "import { DataServer } from '@hydranium/data-server';\nimport { describeErrorWithStack } from '@hydranium/protocol';\n" : ''}// The framework's entry point, NOT Langium's \`@hydranium/langium/lsp\` one. It is
|
|
1046
|
+
const lspImports = `// The framework's entry point, NOT Langium's \`@hydranium/langium/lsp\` one. It is
|
|
1021
1047
|
// signature-compatible and delegates straight through; what it adds first is
|
|
1022
1048
|
// \`assertLspHeadComposed\`, which fails the start if the LSP head's SHARED module
|
|
1023
1049
|
// was never composed. Reaching for Langium's is the natural mistake and it is
|
|
@@ -1025,25 +1051,87 @@ ${data ? "import { DataServer } from '@hydranium/data-server';\nimport { describ
|
|
|
1025
1051
|
// didChangeContent debounce and the last-client-close rebuild are all inert.
|
|
1026
1052
|
import { startLanguageServer, withHydraniumLspFeatures } from '@hydranium/core/lsp';
|
|
1027
1053
|
import { ProposedFeatures, createConnection } from 'vscode-languageserver/node';
|
|
1028
|
-
|
|
1029
|
-
|
|
1054
|
+
`;
|
|
1055
|
+
const lspStart = `
|
|
1030
1056
|
const connection = createConnection(withHydraniumLspFeatures(ProposedFeatures.all));
|
|
1031
1057
|
const { shared } = create__NAME__Services({ connection, ...NodeFileSystem });
|
|
1032
1058
|
startLanguageServer(shared);
|
|
1033
|
-
|
|
1059
|
+
`;
|
|
1060
|
+
// No LSP client names the workspace or asks for the ports here, so the
|
|
1061
|
+
// command line does, and the ports go to stdout once every head listens.
|
|
1062
|
+
const servers = [...(data ? ['dataServer'] : []), ...(glsp ? ['glspServer'] : [])];
|
|
1063
|
+
const socketStart = `
|
|
1064
|
+
const { values, positionals } = parseArgs({
|
|
1065
|
+
options: { ${portFlags.map(flag => `'${flag.slice(2)}': { type: 'string' }`).join(', ')} },
|
|
1066
|
+
allowPositionals: true
|
|
1067
|
+
});
|
|
1068
|
+
// The workspace root: the first argument, else the process cwd.
|
|
1069
|
+
const workspace = positionals[0] ?? process.cwd();
|
|
1070
|
+
|
|
1071
|
+
/** A head's port: its flag, else its environment variable, else 0 for any free port. */
|
|
1072
|
+
function portFrom(flag: keyof typeof values, variable: string): number {
|
|
1073
|
+
const text = values[flag] ?? process.env[variable] ?? '0';
|
|
1074
|
+
const port = Number(text);
|
|
1075
|
+
// Decimal digits only: \`Number\` also reads '' as 0 and takes '1e3' or '0x10'.
|
|
1076
|
+
if (!/^\\d+$/.test(text) || port > 65_535) {
|
|
1077
|
+
throw new Error(\`--\${flag} or \${variable} is '\${text}', not a port\`);
|
|
1078
|
+
}
|
|
1079
|
+
return port;
|
|
1080
|
+
}
|
|
1081
|
+
|
|
1082
|
+
const { shared } = create__NAME__Services({ ...NodeFileSystem });
|
|
1083
|
+
`;
|
|
1084
|
+
const portsLine = `
|
|
1085
|
+
// One JSON line on stdout once every head listens, for the process that started
|
|
1086
|
+
// this one to read the ports from: the one line that starts with \`{\`. Each
|
|
1087
|
+
// head brings the workspace up before it listens; a head that fails to start
|
|
1088
|
+
// has logged why and ends the process, which would otherwise serve without it.
|
|
1089
|
+
Promise.all([${servers.map(server => `${server}.started`).join(', ')}]).then(
|
|
1090
|
+
() => process.stdout.write(\`\${JSON.stringify({ ${servers.map(server => `${server}: ${server}.port`).join(', ')} })}\\n\`),
|
|
1091
|
+
() => process.exit(1)
|
|
1092
|
+
);
|
|
1093
|
+
`;
|
|
1094
|
+
const invocation = lsp
|
|
1095
|
+
? `// Invocation: \`node lib/main.js --stdio\`, or the package's \`__PROJECT_ID__\` bin
|
|
1096
|
+
// script.`
|
|
1097
|
+
: `// Invocation: \`node lib/main.js [<workspace-path>] ${portFlags.map(flag => `[${flag} <port>]`).join(' ')}\`,
|
|
1098
|
+
// or the package's \`__PROJECT_ID__\` bin script. Each port falls back to its
|
|
1099
|
+
// environment variable, then to any free port.`;
|
|
1100
|
+
const dataNote = !data
|
|
1101
|
+
? ''
|
|
1102
|
+
: lsp
|
|
1103
|
+
? `
|
|
1104
|
+
//
|
|
1105
|
+
// NOT the entry the data-server subcommands of \`hydranium-cli\` speak to: stdio
|
|
1106
|
+
// here carries LSP, and the data head is a socket whose port is published over
|
|
1107
|
+
// the LSP connection. Those subcommands spawn \`data-server-main.js\`.`
|
|
1108
|
+
: `
|
|
1109
|
+
//
|
|
1110
|
+
// NOT the entry the data-server subcommands of \`hydranium-cli\` speak to: they
|
|
1111
|
+
// drive the data protocol over a child's stdio, and the data head here is a
|
|
1112
|
+
// socket. Those subcommands spawn \`data-server-main.js\`.`;
|
|
1113
|
+
const text = `${SHEBANG}// Standalone entry point: starts ${headSummary} in the same
|
|
1114
|
+
// process, so every head shares one model store.
|
|
1115
|
+
${invocation}${dataNote}
|
|
1116
|
+
//
|
|
1117
|
+
// Everything here runs at module scope, so this file is an executable rather
|
|
1118
|
+
// than a library entry — import \`./index.js\` instead to compose the language.
|
|
1119
|
+
|
|
1120
|
+
${reflectImport}${glspImports}${importList(coreNodeSymbols, '@hydranium/core/node', columns)}
|
|
1121
|
+
${data ? "import { DataServer } from '@hydranium/data-server';\n" : ''}${data && lsp ? "import { describeErrorWithStack } from '@hydranium/protocol';\n" : ''}${lsp ? lspImports : "import { parseArgs } from 'node:util';\n"}${diagramImports}${transferImports}import { create__NAME__Services } from './language-server/__PROJECT_ID__-module.js';
|
|
1122
|
+
${portImports === '' ? '' : '\n' + portImports}${lsp ? lspStart : socketStart}${dataBlock}${glspBlock}${lsp ? '' : portsLine}`;
|
|
1034
1123
|
return project(text, composition);
|
|
1035
1124
|
}
|
|
1036
1125
|
/**
|
|
1037
1126
|
* The second executable entry: the data head alone, on stdio.
|
|
1038
1127
|
*
|
|
1039
1128
|
* Emitted with the `data` head because it is the ONLY command line that reaches
|
|
1040
|
-
* that head from outside the editor. `main.ts`
|
|
1041
|
-
*
|
|
1042
|
-
*
|
|
1043
|
-
* `hydranium-cli
|
|
1044
|
-
*
|
|
1045
|
-
*
|
|
1046
|
-
* rather than as a missing head.
|
|
1129
|
+
* that head from outside the editor. `main.ts` serves the data head on a
|
|
1130
|
+
* socket, so a client driving the data protocol over a spawned child's
|
|
1131
|
+
* stdin/stdout cannot reach it — which is every data-server subcommand of
|
|
1132
|
+
* `hydranium-cli`. Without this file a scaffolded project has no `--server`
|
|
1133
|
+
* value, and the closest guess, `main.ts`, fails as an unrecognised method or
|
|
1134
|
+
* an unknown flag rather than as a missing head.
|
|
1047
1135
|
*
|
|
1048
1136
|
* A separate process rather than a flag on `main.ts`: only one protocol can own
|
|
1049
1137
|
* stdio, so the two entries are mutually exclusive by construction.
|
|
@@ -1061,12 +1149,17 @@ function dataServerMainFile(composition) {
|
|
|
1061
1149
|
// package's \`__PROJECT_ID__-data-server\` bin script. The workspace path defaults to
|
|
1062
1150
|
// the process cwd, which is what the CLI's \`--cwd\` sets on the child.
|
|
1063
1151
|
//
|
|
1064
|
-
|
|
1152
|
+
${composition.heads.includes('lsp')
|
|
1153
|
+
? `// Contrast with \`main.ts\`, the editor entry: there the LSP head owns stdio and
|
|
1065
1154
|
// the data head is a socket published over the LSP connection. Here there is no
|
|
1066
1155
|
// LSP connection at all, so the workspace initialization an
|
|
1067
1156
|
// \`initialize\`/\`initialized\` pair would otherwise drive has to happen here —
|
|
1068
1157
|
// which is why this entry uses \`startStdioServer\` rather than wiring a
|
|
1069
|
-
// connection directly
|
|
1158
|
+
// connection directly.`
|
|
1159
|
+
: `// Contrast with \`main.ts\`, where the data head is a socket whose port it
|
|
1160
|
+
// prints. Here it owns stdio, and as there, no LSP connection drives the
|
|
1161
|
+
// workspace initialization, so \`startStdioServer\` brings the workspace up
|
|
1162
|
+
// before it listens.`}
|
|
1070
1163
|
//
|
|
1071
1164
|
// Everything here runs at module scope, so this file is an executable rather
|
|
1072
1165
|
// than a library entry — import \`./index.js\` instead to compose the language.
|
|
@@ -1387,8 +1480,9 @@ function readme(composition) {
|
|
|
1387
1480
|
'',
|
|
1388
1481
|
'# Data-head operations. `--server` is a command line the CLI spawns and then',
|
|
1389
1482
|
"# drives the data protocol over the child's stdin/stdout, so it has to name",
|
|
1390
|
-
|
|
1391
|
-
|
|
1483
|
+
...(composition.heads.includes('lsp')
|
|
1484
|
+
? ['# `data-server-main.js` — `main.js` gives stdio to LSP and answers these', '# methods with "Unhandled method".']
|
|
1485
|
+
: ['# `data-server-main.js` — `main.js` serves the data head on a socket.']),
|
|
1392
1486
|
'#',
|
|
1393
1487
|
'# The workspace goes to the ENTRY, not to `--cwd`: `--cwd` re-roots the child,',
|
|
1394
1488
|
'# so a relative entry path is refused by name (an absolute one is fine).',
|
|
@@ -1416,7 +1510,7 @@ function readme(composition) {
|
|
|
1416
1510
|
...composition.grammars
|
|
1417
1511
|
.filter(grammar => grammar.diagram)
|
|
1418
1512
|
.map(grammar => `- \`src/glsp/${grammar.grammarId}/\` — the \`${grammar.grammar}\` diagram: state, storage, submission handler, GModel factory, configuration, create-node handler, DI module`),
|
|
1419
|
-
`- \`../protocol/\` — the \`${memberPackageName(composition, 'protocol')}\` package: what this server and its clients both import (language ids, ${
|
|
1513
|
+
`- \`../protocol/\` — the \`${memberPackageName(composition, 'protocol')}\` package: what this server and its clients both import (language ids, ${headPortConstants(composition).length === 0 ? '' : composition.heads.includes('lsp') ? 'port commands, ' : 'port variables, '}${composition.grammars.some(grammar => grammar.diagram) ? 'diagram ids, ' : ''}the transfer model), written partly by \`npm run generate\``,
|
|
1420
1514
|
'- `test/services.test.ts` — the DI tree composes; grows as your language does',
|
|
1421
1515
|
'- `test/parsing.test.ts` / `linking.test.ts` / `validating.test.ts` — the three tiers a new language breaks first',
|
|
1422
1516
|
'- `test/serialization.test.ts` — each grammar round-trips through its serializer',
|
|
@@ -1775,7 +1869,7 @@ function protocolIndexFile(composition) {
|
|
|
1775
1869
|
const modules = [
|
|
1776
1870
|
'./generated-hydranium/languages.js',
|
|
1777
1871
|
'./generated-hydranium/transfer-model.js',
|
|
1778
|
-
...(
|
|
1872
|
+
...(headPortConstants(composition).length ? ['./head-ports.js'] : []),
|
|
1779
1873
|
...composition.grammars.filter(grammar => grammar.diagram).map(grammar => `./${grammar.grammarId}-diagram-types.js`)
|
|
1780
1874
|
];
|
|
1781
1875
|
const text = `// What the __NAME__ server and its clients both import. A client depends on
|
|
@@ -1799,7 +1893,11 @@ function protocolReadme(composition) {
|
|
|
1799
1893
|
'',
|
|
1800
1894
|
'- `src/generated-hydranium/languages.ts` — each language id and its file extensions',
|
|
1801
1895
|
'- `src/generated-hydranium/transfer-model.ts` — the wire types of the model, references as plain strings',
|
|
1802
|
-
...(
|
|
1896
|
+
...(headPortConstants(composition).length === 0
|
|
1897
|
+
? []
|
|
1898
|
+
: composition.heads.includes('lsp')
|
|
1899
|
+
? ['- `src/head-ports.ts` — the LSP requests a host sends to find the socket heads']
|
|
1900
|
+
: ["- `src/head-ports.ts` — the environment variables naming the socket heads' ports"]),
|
|
1803
1901
|
...composition.grammars
|
|
1804
1902
|
.filter(grammar => grammar.diagram)
|
|
1805
1903
|
.map(grammar => `- \`src/${grammar.grammarId}-diagram-types.ts\` — the \`${grammar.grammar}\` diagram's type ids`),
|
|
@@ -1819,7 +1917,7 @@ function protocolFiles(composition) {
|
|
|
1819
1917
|
ignoreFile('protocol'),
|
|
1820
1918
|
{ path: 'protocol/README.md', content: protocolReadme(composition) },
|
|
1821
1919
|
{ path: 'protocol/src/index.ts', content: protocolIndexFile(composition) },
|
|
1822
|
-
...(
|
|
1920
|
+
...(headPortConstants(composition).length ? [{ path: 'protocol/src/head-ports.ts', content: headPortsFile(composition) }] : []),
|
|
1823
1921
|
...composition.grammars
|
|
1824
1922
|
.filter(grammar => grammar.diagram)
|
|
1825
1923
|
.map(grammar => grammarTemplate('protocol/src/__GRAMMAR_ID__-diagram-types.ts', composition, grammar))
|