@lvce-editor/shared-process 0.122.6 → 0.122.8

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lvce-editor/shared-process",
3
- "version": "0.122.6",
3
+ "version": "0.122.8",
4
4
  "main": "index.js",
5
5
  "type": "module",
6
6
  "keywords": [
@@ -3,6 +3,6 @@ import { fileURLToPath } from 'url'
3
3
 
4
4
  export const getBuiltinExtensionsPath = () => {
5
5
  const staticServerPath = fileURLToPath(import.meta.resolve('@lvce-editor/static-server'))
6
- const builtinExtensionsPath = join(staticServerPath, '..', '..', 'static', 'fe633ed', 'extensions')
6
+ const builtinExtensionsPath = join(staticServerPath, '..', '..', 'static', '6bb0823', 'extensions')
7
7
  return builtinExtensionsPath
8
8
  }
@@ -1,3 +1,4 @@
1
+ import * as Assert from '@lvce-editor/assert'
1
2
  import { existsSync } from 'node:fs'
2
3
  import { mkdir, readFile, writeFile } from 'node:fs/promises'
3
4
  import { dirname } from 'node:path'
@@ -116,7 +117,13 @@ export const getInstalledExtensions = () => {
116
117
  )
117
118
  }
118
119
 
119
- export const getExtensions = () => {
120
+ export const getExtensions = (fields) => {
121
+ if (fields !== undefined) {
122
+ Assert.array(fields)
123
+ for (const field of fields) {
124
+ Assert.string(field)
125
+ }
126
+ }
120
127
  const transientLinkedExtensions = TransientLinkedExtensions.getLinkedExtensions().map((link) => {
121
128
  return {
122
129
  path: link.resolvedPath,
@@ -140,6 +147,7 @@ export const getExtensions = () => {
140
147
  },
141
148
  ],
142
149
  BuiltinExtensionsPath.getBuiltinExtensionsPath(),
150
+ fields,
143
151
  )
144
152
  }
145
153
 
@@ -4,6 +4,7 @@ import * as ExtensionManifestInputType from '../ExtensionManifestInputType/Exten
4
4
  import * as ExtensionManifestsGetFromFolder from './ExtensionManifestsFromFolder.js'
5
5
  import * as ExtensionManifestsGetFromLinkedExtension from './ExtensionManifestsFromLinkedExtension.js'
6
6
  import * as ExtensionManifestsGetFromOnlyExtension from './ExtensionManifestsFromOnlyExtension.js'
7
+ import { selectExtensionManifestFields } from './SelectExtensionManifestFields.js'
7
8
 
8
9
  const getModule = (type) => {
9
10
  switch (type) {
@@ -18,9 +19,9 @@ const getModule = (type) => {
18
19
  }
19
20
  }
20
21
 
21
- const get = (input) => {
22
+ const get = (input, fields) => {
22
23
  const module = getModule(input.type)
23
- return module.getExtensionManifests(input.path)
24
+ return fields === undefined ? module.getExtensionManifests(input.path) : module.getExtensionManifests(input.path, fields)
24
25
  }
25
26
 
26
27
  const isBuiltin = (extension) => {
@@ -37,11 +38,13 @@ const addExtensionDisabledStatus = (uniqueExtensions, disabledExtensionIds, enab
37
38
  })
38
39
  }
39
40
 
40
- export const getAll = async (inputs, builtinExtensionsPath = undefined) => {
41
- const manifests = await Promise.all(inputs.map(get))
41
+ export const getAll = async (inputs, builtinExtensionsPath = undefined, fields) => {
42
+ // Keep identity and enablement fields until deduplication and live enablement have been applied.
43
+ const inputFields = fields === undefined ? undefined : [...new Set([...fields, 'id', 'path', 'disabled'])]
44
+ const manifests = await Promise.all(inputs.map((input) => get(input, inputFields)))
42
45
  const { disabledExtensionIds, enabledExtensionIds } = await getExtensionEnablement()
43
46
  const flatManifests = manifests.flat(1)
44
47
  const uniqueExtensions = DeduplicateExtensions.deduplicateExtensions(flatManifests, builtinExtensionsPath)
45
48
  const filteredExtensions = addExtensionDisabledStatus(uniqueExtensions, disabledExtensionIds, enabledExtensionIds)
46
- return filteredExtensions
49
+ return selectExtensionManifestFields(filteredExtensions, fields)
47
50
  }
@@ -7,6 +7,7 @@ import * as IsEnoentError from '../IsEnoentError/IsEnoentError.js'
7
7
  import * as Platform from '../Platform/Platform.js'
8
8
  import * as ToAbsolutePaths from '../ToAbsolutePaths/ToAbsolutePaths.js'
9
9
  import { VError } from '../VError/VError.js'
10
+ import { selectExtensionManifestFields } from './SelectExtensionManifestFields.js'
10
11
 
11
12
  let builtinManifests
12
13
 
@@ -17,7 +18,7 @@ const readExtensionManifests = async (path) => {
17
18
  return Promise.all(absolutePaths.map(ExtensionManifest.get))
18
19
  }
19
20
 
20
- export const getExtensionManifests = async (path) => {
21
+ export const getExtensionManifests = async (path, fields) => {
21
22
  let cached
22
23
  try {
23
24
  if (!path) {
@@ -25,7 +26,7 @@ export const getExtensionManifests = async (path) => {
25
26
  }
26
27
  // Packaged builtins are fixed for this process. User and development extensions stay live.
27
28
  if (!Platform.isProduction || path !== BuiltinExtensionsPath.getBuiltinExtensionsPath()) {
28
- return await readExtensionManifests(path)
29
+ return selectExtensionManifestFields(await readExtensionManifests(path), fields)
29
30
  }
30
31
  if (!builtinManifests || builtinManifests.path !== path) {
31
32
  builtinManifests = { path, promise: readExtensionManifests(path) }
@@ -36,10 +37,10 @@ export const getExtensionManifests = async (path) => {
36
37
  if (builtinManifests === cached) {
37
38
  builtinManifests = undefined
38
39
  }
39
- return manifests
40
+ return selectExtensionManifestFields(manifests, fields)
40
41
  }
41
42
  // Keep request-local metadata and nested contributions independent of the cached values.
42
- return structuredClone(manifests)
43
+ return structuredClone(selectExtensionManifestFields(manifests, fields))
43
44
  } catch (error) {
44
45
  if (cached && builtinManifests === cached) {
45
46
  builtinManifests = undefined
@@ -0,0 +1,8 @@
1
+ export const selectExtensionManifestFields = (manifests, fields) => {
2
+ if (fields === undefined) {
3
+ return manifests
4
+ }
5
+ return manifests.map((manifest) =>
6
+ Object.fromEntries(fields.filter((field) => Object.hasOwn(manifest, field)).map((field) => [field, manifest[field]])),
7
+ )
8
+ }
@@ -21,6 +21,7 @@ import { normalizeLanguageServerDocumentUri } from '../NormalizeLanguageServerDo
21
21
 
22
22
 
23
23
 
24
+
24
25
 
25
26
 
26
27
 
@@ -147,6 +148,9 @@ const wait = (duration) => {
147
148
  }
148
149
 
149
150
  const PublishDiagnosticsTimeout = 1_000
151
+ // Push servers can publish several diagnostic stages, including an unchanged
152
+ // intermediate result after didChange. Collect the burst before returning it.
153
+ const PublishDiagnosticsSettleTime = 300
150
154
 
151
155
  export class LanguageServerConnection {
152
156
  child
@@ -267,7 +271,7 @@ export class LanguageServerConnection {
267
271
  const previous = this.documents.get(textDocument.uri)
268
272
  const documentChanged = !previous || previous.languageId !== textDocument.languageId || previous.text !== textDocument.text
269
273
  const cached = this.publishedDiagnostics.get(textDocument.uri)
270
- if (!documentChanged && cached) {
274
+ if (!documentChanged && cached && !this.diagnosticWaiters.has(textDocument.uri)) {
271
275
  return cached
272
276
  }
273
277
  const diagnostics = this.waitForPublishedDiagnostics(textDocument.uri)
@@ -510,9 +514,8 @@ export class LanguageServerConnection {
510
514
  if (!waiters) {
511
515
  return
512
516
  }
513
- this.diagnosticWaiters.delete(normalizedUri)
514
517
  for (const waiter of waiters) {
515
- waiter.resolve(diagnostics)
518
+ waiter.publish(diagnostics)
516
519
  }
517
520
  }
518
521
 
@@ -614,22 +617,31 @@ export class LanguageServerConnection {
614
617
  return new Promise ((resolve, reject) => {
615
618
  const waiters = this.diagnosticWaiters.get(uri) || new Set()
616
619
  let timeout
620
+ let settling
621
+ const removeWaiter = () => {
622
+ clearTimeout(timeout)
623
+ clearTimeout(settling)
624
+ waiters.delete(waiter)
625
+ if (waiters.size === 0) {
626
+ this.diagnosticWaiters.delete(uri)
627
+ }
628
+ }
617
629
  const waiter = {
630
+ publish(value) {
631
+ clearTimeout(settling)
632
+ settling = setTimeout(() => waiter.resolve(value), PublishDiagnosticsSettleTime)
633
+ },
618
634
  reject(error) {
619
- clearTimeout(timeout)
635
+ removeWaiter()
620
636
  reject(error)
621
637
  },
622
638
  resolve(value) {
623
- clearTimeout(timeout)
639
+ removeWaiter()
624
640
  resolve(value)
625
641
  },
626
642
  }
627
643
  timeout = setTimeout(() => {
628
- waiters.delete(waiter)
629
- if (waiters.size === 0) {
630
- this.diagnosticWaiters.delete(uri)
631
- }
632
- resolve(this.publishedDiagnostics.get(uri) || [])
644
+ waiter.resolve(this.publishedDiagnostics.get(uri) || [])
633
645
  }, PublishDiagnosticsTimeout)
634
646
  waiters.add(waiter)
635
647
  this.diagnosticWaiters.set(uri, waiters)
@@ -56,11 +56,11 @@ export const getSetupName = () => {
56
56
  return 'Lvce-Setup'
57
57
  }
58
58
 
59
- export const version = '0.122.6'
59
+ export const version = '0.122.8'
60
60
 
61
- export const commit = 'fe633ed'
61
+ export const commit = '6bb0823'
62
62
 
63
- export const date = '2026-10-12T11:39:04.000Z'
63
+ export const date = '2026-10-12T15:00:47.000Z'
64
64
 
65
65
  export const getVersion = () => {
66
66
  return version
@@ -2,5 +2,5 @@ import { join } from 'node:path'
2
2
  import * as Root from '../Root/Root.js'
3
3
 
4
4
  export const getPreloadUrl = () => {
5
- return join(Root.root, 'static', 'fe633ed', 'packages', 'preload', 'dist', 'index.js')
5
+ return join(Root.root, 'static', '6bb0823', 'packages', 'preload', 'dist', 'index.js')
6
6
  }