@lorepack/cli 0.0.0-stage → 0.1.0-alpha.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/dist/.tsbuildinfo +1 -0
- package/dist/commands/activate.d.ts +20 -0
- package/dist/commands/activate.d.ts.map +1 -0
- package/dist/commands/activate.js +171 -0
- package/dist/commands/activate.js.map +1 -0
- package/dist/commands/build.d.ts +3 -0
- package/dist/commands/build.d.ts.map +1 -0
- package/dist/commands/build.js +53 -0
- package/dist/commands/build.js.map +1 -0
- package/dist/commands/config.d.ts +14 -0
- package/dist/commands/config.d.ts.map +1 -0
- package/dist/commands/config.js +109 -0
- package/dist/commands/config.js.map +1 -0
- package/dist/commands/connect.d.ts +5 -0
- package/dist/commands/connect.d.ts.map +1 -0
- package/dist/commands/connect.js +196 -0
- package/dist/commands/connect.js.map +1 -0
- package/dist/commands/deploy.d.ts +14 -0
- package/dist/commands/deploy.d.ts.map +1 -0
- package/dist/commands/deploy.js +248 -0
- package/dist/commands/deploy.js.map +1 -0
- package/dist/commands/dev.d.ts +25 -0
- package/dist/commands/dev.d.ts.map +1 -0
- package/dist/commands/dev.js +227 -0
- package/dist/commands/dev.js.map +1 -0
- package/dist/commands/diff.d.ts +3 -0
- package/dist/commands/diff.d.ts.map +1 -0
- package/dist/commands/diff.js +75 -0
- package/dist/commands/diff.js.map +1 -0
- package/dist/commands/doctor.d.ts +14 -0
- package/dist/commands/doctor.d.ts.map +1 -0
- package/dist/commands/doctor.js +96 -0
- package/dist/commands/doctor.js.map +1 -0
- package/dist/commands/export.d.ts +3 -0
- package/dist/commands/export.d.ts.map +1 -0
- package/dist/commands/export.js +126 -0
- package/dist/commands/export.js.map +1 -0
- package/dist/commands/index.d.ts +8 -0
- package/dist/commands/index.d.ts.map +1 -0
- package/dist/commands/index.js +51 -0
- package/dist/commands/index.js.map +1 -0
- package/dist/commands/init.d.ts +3 -0
- package/dist/commands/init.d.ts.map +1 -0
- package/dist/commands/init.js +95 -0
- package/dist/commands/init.js.map +1 -0
- package/dist/commands/inspect.d.ts +15 -0
- package/dist/commands/inspect.d.ts.map +1 -0
- package/dist/commands/inspect.js +527 -0
- package/dist/commands/inspect.js.map +1 -0
- package/dist/commands/mcp.d.ts +12 -0
- package/dist/commands/mcp.d.ts.map +1 -0
- package/dist/commands/mcp.js +219 -0
- package/dist/commands/mcp.js.map +1 -0
- package/dist/commands/pack.d.ts +9 -0
- package/dist/commands/pack.d.ts.map +1 -0
- package/dist/commands/pack.js +57 -0
- package/dist/commands/pack.js.map +1 -0
- package/dist/commands/plan.d.ts +3 -0
- package/dist/commands/plan.d.ts.map +1 -0
- package/dist/commands/plan.js +44 -0
- package/dist/commands/plan.js.map +1 -0
- package/dist/commands/prune.d.ts +7 -0
- package/dist/commands/prune.d.ts.map +1 -0
- package/dist/commands/prune.js +341 -0
- package/dist/commands/prune.js.map +1 -0
- package/dist/commands/search.d.ts +3 -0
- package/dist/commands/search.d.ts.map +1 -0
- package/dist/commands/search.js +84 -0
- package/dist/commands/search.js.map +1 -0
- package/dist/commands/serve.d.ts +20 -0
- package/dist/commands/serve.d.ts.map +1 -0
- package/dist/commands/serve.js +66 -0
- package/dist/commands/serve.js.map +1 -0
- package/dist/commands/status.d.ts +3 -0
- package/dist/commands/status.d.ts.map +1 -0
- package/dist/commands/status.js +27 -0
- package/dist/commands/status.js.map +1 -0
- package/dist/commands/target.d.ts +71 -0
- package/dist/commands/target.d.ts.map +1 -0
- package/dist/commands/target.js +945 -0
- package/dist/commands/target.js.map +1 -0
- package/dist/entry.d.ts +3 -0
- package/dist/entry.d.ts.map +1 -0
- package/dist/entry.js +19 -0
- package/dist/entry.js.map +1 -0
- package/dist/framework/context.d.ts +49 -0
- package/dist/framework/context.d.ts.map +1 -0
- package/dist/framework/context.js +47 -0
- package/dist/framework/context.js.map +1 -0
- package/dist/framework/exit.d.ts +36 -0
- package/dist/framework/exit.d.ts.map +1 -0
- package/dist/framework/exit.js +57 -0
- package/dist/framework/exit.js.map +1 -0
- package/dist/framework/metadata.d.ts +38 -0
- package/dist/framework/metadata.d.ts.map +1 -0
- package/dist/framework/metadata.js +47 -0
- package/dist/framework/metadata.js.map +1 -0
- package/dist/framework/program.d.ts +47 -0
- package/dist/framework/program.d.ts.map +1 -0
- package/dist/framework/program.js +189 -0
- package/dist/framework/program.js.map +1 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +7 -0
- package/dist/index.js.map +1 -0
- package/dist/migrations/README.md +7 -0
- package/dist/migrations/build/0001_catalog.sql +85 -0
- package/dist/migrations/build/0002_tables.sql +43 -0
- package/dist/migrations/build/0003_table-cell-range.sql +13 -0
- package/dist/migrations/build/0004_chunk-page.sql +11 -0
- package/dist/migrations/state/0001_state.sql +40 -0
- package/dist/public-entry.js +38563 -0
- package/dist/public-entry.js.map +7 -0
- package/dist/public-index.js +36428 -0
- package/dist/public-index.js.map +7 -0
- package/dist/services/build.d.ts +48 -0
- package/dist/services/build.d.ts.map +1 -0
- package/dist/services/build.js +499 -0
- package/dist/services/build.js.map +1 -0
- package/dist/services/builds.d.ts +40 -0
- package/dist/services/builds.d.ts.map +1 -0
- package/dist/services/builds.js +184 -0
- package/dist/services/builds.js.map +1 -0
- package/dist/services/cancellation.d.ts +27 -0
- package/dist/services/cancellation.d.ts.map +1 -0
- package/dist/services/cancellation.js +41 -0
- package/dist/services/cancellation.js.map +1 -0
- package/dist/services/cloudflare-target.d.ts +38 -0
- package/dist/services/cloudflare-target.d.ts.map +1 -0
- package/dist/services/cloudflare-target.js +471 -0
- package/dist/services/cloudflare-target.js.map +1 -0
- package/dist/services/comparer.d.ts +15 -0
- package/dist/services/comparer.d.ts.map +1 -0
- package/dist/services/comparer.js +43 -0
- package/dist/services/comparer.js.map +1 -0
- package/dist/services/config-resolve.d.ts +60 -0
- package/dist/services/config-resolve.d.ts.map +1 -0
- package/dist/services/config-resolve.js +178 -0
- package/dist/services/config-resolve.js.map +1 -0
- package/dist/services/deploy.d.ts +70 -0
- package/dist/services/deploy.d.ts.map +1 -0
- package/dist/services/deploy.js +260 -0
- package/dist/services/deploy.js.map +1 -0
- package/dist/services/dev-session.d.ts +52 -0
- package/dist/services/dev-session.d.ts.map +1 -0
- package/dist/services/dev-session.js +102 -0
- package/dist/services/dev-session.js.map +1 -0
- package/dist/services/doctor.d.ts +35 -0
- package/dist/services/doctor.d.ts.map +1 -0
- package/dist/services/doctor.js +389 -0
- package/dist/services/doctor.js.map +1 -0
- package/dist/services/export.d.ts +20 -0
- package/dist/services/export.d.ts.map +1 -0
- package/dist/services/export.js +129 -0
- package/dist/services/export.js.map +1 -0
- package/dist/services/init.d.ts +46 -0
- package/dist/services/init.d.ts.map +1 -0
- package/dist/services/init.js +231 -0
- package/dist/services/init.js.map +1 -0
- package/dist/services/packing.d.ts +25 -0
- package/dist/services/packing.d.ts.map +1 -0
- package/dist/services/packing.js +69 -0
- package/dist/services/packing.js.map +1 -0
- package/dist/services/parse-cache.d.ts +47 -0
- package/dist/services/parse-cache.d.ts.map +1 -0
- package/dist/services/parse-cache.js +65 -0
- package/dist/services/parse-cache.js.map +1 -0
- package/dist/services/project.d.ts +49 -0
- package/dist/services/project.d.ts.map +1 -0
- package/dist/services/project.js +119 -0
- package/dist/services/project.js.map +1 -0
- package/dist/services/remote-prune.d.ts +7 -0
- package/dist/services/remote-prune.d.ts.map +1 -0
- package/dist/services/remote-prune.js +34 -0
- package/dist/services/remote-prune.js.map +1 -0
- package/dist/services/retention.d.ts +20 -0
- package/dist/services/retention.d.ts.map +1 -0
- package/dist/services/retention.js +106 -0
- package/dist/services/retention.js.map +1 -0
- package/dist/services/revalidate.d.ts +36 -0
- package/dist/services/revalidate.d.ts.map +1 -0
- package/dist/services/revalidate.js +73 -0
- package/dist/services/revalidate.js.map +1 -0
- package/dist/services/search.d.ts +25 -0
- package/dist/services/search.d.ts.map +1 -0
- package/dist/services/search.js +88 -0
- package/dist/services/search.js.map +1 -0
- package/dist/services/serving.d.ts +70 -0
- package/dist/services/serving.d.ts.map +1 -0
- package/dist/services/serving.js +240 -0
- package/dist/services/serving.js.map +1 -0
- package/dist/services/status.d.ts +54 -0
- package/dist/services/status.d.ts.map +1 -0
- package/dist/services/status.js +203 -0
- package/dist/services/status.js.map +1 -0
- package/dist/services/studio-assets.d.ts +13 -0
- package/dist/services/studio-assets.d.ts.map +1 -0
- package/dist/services/studio-assets.js +94 -0
- package/dist/services/studio-assets.js.map +1 -0
- package/dist/services/studio-diagnostics.d.ts +28 -0
- package/dist/services/studio-diagnostics.d.ts.map +1 -0
- package/dist/services/studio-diagnostics.js +88 -0
- package/dist/services/studio-diagnostics.js.map +1 -0
- package/dist/services/studio-endpoints.d.ts +61 -0
- package/dist/services/studio-endpoints.d.ts.map +1 -0
- package/dist/services/studio-endpoints.js +88 -0
- package/dist/services/studio-endpoints.js.map +1 -0
- package/dist/services/studio-mutations.d.ts +32 -0
- package/dist/services/studio-mutations.d.ts.map +1 -0
- package/dist/services/studio-mutations.js +149 -0
- package/dist/services/studio-mutations.js.map +1 -0
- package/dist/services/versions.d.ts +38 -0
- package/dist/services/versions.d.ts.map +1 -0
- package/dist/services/versions.js +46 -0
- package/dist/services/versions.js.map +1 -0
- package/dist/services/watch.d.ts +103 -0
- package/dist/services/watch.d.ts.map +1 -0
- package/dist/services/watch.js +420 -0
- package/dist/services/watch.js.map +1 -0
- package/package.json +73 -4
- package/studio-dist/assets/ibm-plex-mono-latin-400-normal-Dm_PoFIZ.woff2 +0 -0
- package/studio-dist/assets/ibm-plex-mono-latin-500-normal-C_OblDzq.woff2 +0 -0
- package/studio-dist/assets/ibm-plex-sans-latin-400-normal-CDDApCn2.woff2 +0 -0
- package/studio-dist/assets/ibm-plex-sans-latin-500-normal-6ng42L7E.woff2 +0 -0
- package/studio-dist/assets/ibm-plex-sans-latin-600-normal-CuJfVYMP.woff2 +0 -0
- package/studio-dist/assets/index-BuAYbQVX.js +66 -0
- package/studio-dist/assets/index-C_3XEUt4.css +1 -0
- package/studio-dist/index.html +30 -0
- package/README.md +0 -3
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { sealCandidateDirectory } from '@lorepack/backend-local';
|
|
2
|
+
import { type BuildId, type BuildManifest, type LoadedConfig, type ProgressBus } from '@lorepack/core';
|
|
3
|
+
export interface BuildOptions {
|
|
4
|
+
readonly config: LoadedConfig;
|
|
5
|
+
readonly progress: ProgressBus;
|
|
6
|
+
readonly frozen?: boolean;
|
|
7
|
+
readonly activate?: boolean;
|
|
8
|
+
readonly allowLargeProject?: boolean;
|
|
9
|
+
readonly signal?: AbortSignal;
|
|
10
|
+
/** How long to wait for the project lock. Tests use a short wait; users get the default. */
|
|
11
|
+
readonly lockWaitMs?: number;
|
|
12
|
+
readonly now?: () => Date;
|
|
13
|
+
readonly seal?: typeof sealCandidateDirectory;
|
|
14
|
+
}
|
|
15
|
+
export interface BuildResult {
|
|
16
|
+
readonly buildId: BuildId;
|
|
17
|
+
readonly created: boolean;
|
|
18
|
+
readonly activated: boolean;
|
|
19
|
+
readonly counts: BuildManifest['counts'];
|
|
20
|
+
readonly warnings: number;
|
|
21
|
+
readonly reusedArtifacts: number;
|
|
22
|
+
readonly rebuiltArtifacts: number;
|
|
23
|
+
readonly durationMs: number;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* How long a command waits for the project lock, when the environment asks for something
|
|
27
|
+
* other than the shipped default.
|
|
28
|
+
*
|
|
29
|
+
* `LORE_LOCK_WAIT_MS` exists because 30 seconds is the right default and the wrong constant
|
|
30
|
+
* to have no way around (#229). It is the time a person is willing to look at a command that
|
|
31
|
+
* appears to be doing nothing, and it is unrelated to how long a large project on a slow disk
|
|
32
|
+
* legitimately takes to build. A Windows CI runner building a 500-document fixture exceeds it,
|
|
33
|
+
* and the honest fix is to let that environment say so rather than to make every session wait
|
|
34
|
+
* longer for a lock that is genuinely stuck.
|
|
35
|
+
*
|
|
36
|
+
* Operational, so it is an environment variable rather than configuration: it never reaches
|
|
37
|
+
* the build id, and two machines that disagree about it still produce identical builds.
|
|
38
|
+
*/
|
|
39
|
+
export declare function lockWaitFromEnvironment(environment?: NodeJS.ProcessEnv): number | undefined;
|
|
40
|
+
export declare function runBuild(options: BuildOptions): Promise<BuildResult>;
|
|
41
|
+
/**
|
|
42
|
+
* Re-reads a source after fingerprinting and binds the bytes handed to the parser to that
|
|
43
|
+
* digest. A source can be edited between the fingerprint and parse stages, so trusting the
|
|
44
|
+
* first hash would record one set of bytes under another set's identity and poison the parse
|
|
45
|
+
* cache. One retry handles an in-flight save; a second mismatch fails the candidate.
|
|
46
|
+
*/
|
|
47
|
+
export declare function readStableSourceBytes(absolutePath: string, expectedHash: string, displayPath: string): Uint8Array;
|
|
48
|
+
//# sourceMappingURL=build.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"build.d.ts","sourceRoot":"","sources":["../../src/services/build.ts"],"names":[],"mappings":"AAEA,OAAO,EAYL,sBAAsB,EAIvB,MAAM,yBAAyB,CAAC;AAgBjC,OAAO,EACL,KAAK,OAAO,EACZ,KAAK,aAAa,EASlB,KAAK,YAAY,EAKjB,KAAK,WAAW,EAIjB,MAAM,gBAAgB,CAAC;AAmBxB,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,MAAM,EAAE,YAAY,CAAC;IAC9B,QAAQ,CAAC,QAAQ,EAAE,WAAW,CAAC;IAC/B,QAAQ,CAAC,MAAM,CAAC,EAAE,OAAO,CAAC;IAC1B,QAAQ,CAAC,QAAQ,CAAC,EAAE,OAAO,CAAC;IAC5B,QAAQ,CAAC,iBAAiB,CAAC,EAAE,OAAO,CAAC;IACrC,QAAQ,CAAC,MAAM,CAAC,EAAE,WAAW,CAAC;IAC9B,4FAA4F;IAC5F,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,IAAI,CAAC;IAC1B,QAAQ,CAAC,IAAI,CAAC,EAAE,OAAO,sBAAsB,CAAC;CAC/C;AAwBD,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAC1B,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAC1B,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAC;IAC5B,QAAQ,CAAC,MAAM,EAAE,aAAa,CAAC,QAAQ,CAAC,CAAC;IACzC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,eAAe,EAAE,MAAM,CAAC;IACjC,QAAQ,CAAC,gBAAgB,EAAE,MAAM,CAAC;IAClC,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;CAC7B;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,uBAAuB,CACrC,WAAW,GAAE,MAAM,CAAC,UAAwB,GAC3C,MAAM,GAAG,SAAS,CAepB;AAED,wBAAsB,QAAQ,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,WAAW,CAAC,CAma1E;AAED;;;;;GAKG;AACH,wBAAgB,qBAAqB,CACnC,YAAY,EAAE,MAAM,EACpB,YAAY,EAAE,MAAM,EACpB,WAAW,EAAE,MAAM,GAClB,UAAU,CAuBZ"}
|
|
@@ -0,0 +1,499 @@
|
|
|
1
|
+
import { readFileSync, rmSync } from 'node:fs';
|
|
2
|
+
import { join } from 'node:path';
|
|
3
|
+
import { buildMigrationsDirectory, countRows, createCandidateDirectory, discardCandidateDirectory, FileObjectStore, integrityCheck, LocalStateStore, loadMigrations, openWritable, ProjectLock, runMigrations, sealCandidateDirectory, searchCatalog, stateMigrationsDirectory, writeCatalog, } from '@lorepack/backend-local';
|
|
4
|
+
import { assertNoDrift, buildLockfile, cacheKey, chunkArtifact, compareLockfiles, createPlan, normalizeArtifact, readLockfile, resolveRules, validateCandidate, writeLockfile, } from '@lorepack/compiler';
|
|
5
|
+
import { buildManifestSchema, CANONICALIZATION_VERSION, count, deriveBuildId, hashCanonical, hashRoot, LORE_DIRECTORY, LoreError, NORMALIZATION_VERSION, secretsFromEnv, sha256Hex, writeFileAtomic, } from '@lorepack/core';
|
|
6
|
+
import { parserFor } from '@lorepack/parsers';
|
|
7
|
+
import { checkpoint } from './cancellation.js';
|
|
8
|
+
import { ParseCache } from './parse-cache.js';
|
|
9
|
+
import { isBuildReadable, readBuildCatalog } from './project.js';
|
|
10
|
+
import { lockInputs } from './versions.js';
|
|
11
|
+
/**
|
|
12
|
+
* The build orchestrator.
|
|
13
|
+
*
|
|
14
|
+
* Stage order matters and is the whole point: validate the candidate **in place**, then
|
|
15
|
+
* seal it into `builds/`, then record it, and only then activate as a separate step. A
|
|
16
|
+
* candidate lives under `.lore/tmp/` until it has passed, so an interrupted or failed
|
|
17
|
+
* build cannot leave something in `builds/` that a later run would treat as real.
|
|
18
|
+
*/
|
|
19
|
+
/** The `applied_at` recorded inside every build database. See `runMigrations` below. */
|
|
20
|
+
const SEALED_AT = '1980-01-01T00:00:00.000Z';
|
|
21
|
+
/**
|
|
22
|
+
* The class a reader groups by. Both ways of being unreadable are the same fact to a user
|
|
23
|
+
* ("this file is not in the build"), so they share a class and differ in code.
|
|
24
|
+
*/
|
|
25
|
+
function warningClass(code) {
|
|
26
|
+
return code === 'unsupported-format' || code === 'undecodable-content'
|
|
27
|
+
? 'unsupported-file'
|
|
28
|
+
: 'parser';
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* How long a command waits for the project lock, when the environment asks for something
|
|
32
|
+
* other than the shipped default.
|
|
33
|
+
*
|
|
34
|
+
* `LORE_LOCK_WAIT_MS` exists because 30 seconds is the right default and the wrong constant
|
|
35
|
+
* to have no way around (#229). It is the time a person is willing to look at a command that
|
|
36
|
+
* appears to be doing nothing, and it is unrelated to how long a large project on a slow disk
|
|
37
|
+
* legitimately takes to build. A Windows CI runner building a 500-document fixture exceeds it,
|
|
38
|
+
* and the honest fix is to let that environment say so rather than to make every session wait
|
|
39
|
+
* longer for a lock that is genuinely stuck.
|
|
40
|
+
*
|
|
41
|
+
* Operational, so it is an environment variable rather than configuration: it never reaches
|
|
42
|
+
* the build id, and two machines that disagree about it still produce identical builds.
|
|
43
|
+
*/
|
|
44
|
+
export function lockWaitFromEnvironment(environment = process.env) {
|
|
45
|
+
const raw = environment.LORE_LOCK_WAIT_MS;
|
|
46
|
+
if (raw === undefined)
|
|
47
|
+
return undefined;
|
|
48
|
+
// `Number('')` is 0, and 0 here means "do not wait at all", which is the opposite of what
|
|
49
|
+
// someone setting a wait wants. An unset variable expands to the empty string in a shell,
|
|
50
|
+
// so reaching that by accident is easy (#195 is the same trap on a different knob).
|
|
51
|
+
const value = raw.trim() === '' ? Number.NaN : Number(raw);
|
|
52
|
+
if (!Number.isFinite(value) || value < 0) {
|
|
53
|
+
throw new LoreError('LORE_E_INVALID_ARGUMENT', `LORE_LOCK_WAIT_MS must be a number of milliseconds, got ${raw}.`, { remediation: 'Set it to milliseconds, or unset it to wait the default 30 seconds.' });
|
|
54
|
+
}
|
|
55
|
+
return value;
|
|
56
|
+
}
|
|
57
|
+
export async function runBuild(options) {
|
|
58
|
+
const { config, progress } = options;
|
|
59
|
+
const now = options.now ?? (() => new Date());
|
|
60
|
+
const startedAt = now();
|
|
61
|
+
const loreDirectory = join(config.projectRoot, LORE_DIRECTORY);
|
|
62
|
+
const waitMs = options.lockWaitMs ?? lockWaitFromEnvironment();
|
|
63
|
+
const lock = new ProjectLock(join(loreDirectory, 'lock'), {
|
|
64
|
+
...(waitMs === undefined ? {} : { waitMs }),
|
|
65
|
+
onWait: ({ pid }) => progress.diagnostic('info', pid === null
|
|
66
|
+
? 'Waiting for the project lock held by another Lorepack process.'
|
|
67
|
+
: `Waiting for the project lock held by pid ${pid}.`),
|
|
68
|
+
});
|
|
69
|
+
return lock.withLock(async () => {
|
|
70
|
+
const state = LocalStateStore.open(loreDirectory, stateMigrationsDirectory());
|
|
71
|
+
const objects = new FileObjectStore(join(loreDirectory, 'objects'));
|
|
72
|
+
try {
|
|
73
|
+
const previousLock = readLockfile(config.projectRoot);
|
|
74
|
+
const nextLock = buildLockfile(lockInputs());
|
|
75
|
+
if (options.frozen === true)
|
|
76
|
+
assertNoDrift(compareLockfiles(previousLock, nextLock));
|
|
77
|
+
const active = state.current();
|
|
78
|
+
const previous = active === null ? null : readBuildCatalog(loreDirectory, active.buildId);
|
|
79
|
+
const { discovery, fingerprint } = await createPlan({
|
|
80
|
+
config,
|
|
81
|
+
previous,
|
|
82
|
+
previousLock,
|
|
83
|
+
lockInputs: lockInputs(),
|
|
84
|
+
progress,
|
|
85
|
+
...(options.allowLargeProject === undefined
|
|
86
|
+
? {}
|
|
87
|
+
: { allowLargeProject: options.allowLargeProject }),
|
|
88
|
+
});
|
|
89
|
+
await checkpoint(options.signal, { hasActiveBuild: active !== null });
|
|
90
|
+
// Rules resolve here, before parsing, because the cache key depends on them: an
|
|
91
|
+
// artifact whose declared authority changed must be reindexed even though its bytes
|
|
92
|
+
// did not (architecture section 12.7). Resolving after the parse loop would let a rule
|
|
93
|
+
// edit reuse a stale entry, which is the quiet failure the cache key exists to prevent.
|
|
94
|
+
const ruleResolution = resolveRules({
|
|
95
|
+
artifacts: fingerprint.artifacts.map((artifact) => ({
|
|
96
|
+
artifactId: artifact.artifactId,
|
|
97
|
+
relativePath: artifact.relativePath,
|
|
98
|
+
})),
|
|
99
|
+
config: config.effective,
|
|
100
|
+
});
|
|
101
|
+
const rulesById = new Map(ruleResolution.resolved.map((entry) => [entry.artifactId, entry]));
|
|
102
|
+
const cache = new ParseCache(join(loreDirectory, 'cache', 'parse'));
|
|
103
|
+
progress.start('parsing', 'Parsing', fingerprint.artifacts.length);
|
|
104
|
+
const parsed = [];
|
|
105
|
+
let handled = 0;
|
|
106
|
+
for (const discovered of fingerprint.artifacts) {
|
|
107
|
+
await checkpoint(options.signal, { hasActiveBuild: active !== null });
|
|
108
|
+
const parser = parserFor({
|
|
109
|
+
mediaType: discovered.mediaType,
|
|
110
|
+
relativePath: discovered.relativePath,
|
|
111
|
+
});
|
|
112
|
+
if (parser === null)
|
|
113
|
+
continue;
|
|
114
|
+
const key = cacheKey({
|
|
115
|
+
artifactId: discovered.artifactId,
|
|
116
|
+
contentHash: discovered.contentHash,
|
|
117
|
+
parserId: parser.id,
|
|
118
|
+
parserVersion: parser.version,
|
|
119
|
+
normalizationVersion: NORMALIZATION_VERSION,
|
|
120
|
+
chunking: config.effective.chunking,
|
|
121
|
+
rules: ruleResolution.canonical,
|
|
122
|
+
});
|
|
123
|
+
const bytes = readStableSourceBytes(discovered.absolutePath, discovered.contentHash, discovered.displayPath);
|
|
124
|
+
// A hit still has to have its normalized body present: the object store and the
|
|
125
|
+
// cache can be pruned independently, and reusing a parse whose body is gone would
|
|
126
|
+
// produce a build that cannot answer a source read.
|
|
127
|
+
const cached = cache.get(key);
|
|
128
|
+
if (cached !== null && (await objects.has(cached.objectHash))) {
|
|
129
|
+
parsed.push(withRules(cached, rulesById));
|
|
130
|
+
handled += 1;
|
|
131
|
+
continue;
|
|
132
|
+
}
|
|
133
|
+
let result;
|
|
134
|
+
try {
|
|
135
|
+
// Awaited because a parser may be asynchronous: PDF and DOCX cannot be read any
|
|
136
|
+
// other way. The `await` matters for the `catch` as much as for the value, since
|
|
137
|
+
// a rejected promise from an unawaited call would escape this block entirely and
|
|
138
|
+
// surface as an unhandled rejection rather than as `LORE_E_PARSE_FAILED`.
|
|
139
|
+
result = await parser.parse({
|
|
140
|
+
artifactId: discovered.artifactId,
|
|
141
|
+
sourceId: discovered.sourceId,
|
|
142
|
+
relativePath: discovered.relativePath,
|
|
143
|
+
displayPath: discovered.displayPath,
|
|
144
|
+
mediaType: discovered.mediaType,
|
|
145
|
+
byteSize: discovered.byteSize,
|
|
146
|
+
contentHash: discovered.contentHash,
|
|
147
|
+
bytes,
|
|
148
|
+
});
|
|
149
|
+
}
|
|
150
|
+
catch (cause) {
|
|
151
|
+
// A parser that raised a `LoreError` classified its own failure, and that
|
|
152
|
+
// classification is kept (#242).
|
|
153
|
+
//
|
|
154
|
+
// Wrapping everything meant a parser raising `LORE_E_ENVELOPE_EXCEEDED`, a user
|
|
155
|
+
// problem that exits 1, was reported as `LORE_E_PARSE_FAILED`, a build integrity
|
|
156
|
+
// failure that exits 2. The parser was right and the pipeline overrode it, so
|
|
157
|
+
// anything branching on the stable code, which is what the taxonomy is for, was
|
|
158
|
+
// told the wrong thing.
|
|
159
|
+
if (cause instanceof LoreError)
|
|
160
|
+
throw cause;
|
|
161
|
+
// Anything else is a genuine surprise, and that is exactly what this code means:
|
|
162
|
+
// a supported, included file whose bytes could not be read. It fails the candidate
|
|
163
|
+
// by default (architecture section 6.9) and the previous build stays active.
|
|
164
|
+
//
|
|
165
|
+
// A file whose bytes are not readable text does not reach here: fingerprinting
|
|
166
|
+
// classified it and left it out with a warning, which is the other row of the
|
|
167
|
+
// same table (#165).
|
|
168
|
+
throw new LoreError('LORE_E_PARSE_FAILED', `Could not parse ${discovered.displayPath}.`, {
|
|
169
|
+
remediation: 'Fix the file, or exclude it in .loreignore. The active build is unchanged.',
|
|
170
|
+
path: discovered.displayPath,
|
|
171
|
+
cause,
|
|
172
|
+
});
|
|
173
|
+
}
|
|
174
|
+
const normalized = await normalizeArtifact({ parsed: result, objects });
|
|
175
|
+
const entry = {
|
|
176
|
+
artifact: result.artifact,
|
|
177
|
+
nodes: normalized.nodes,
|
|
178
|
+
chunks: chunkArtifact({
|
|
179
|
+
artifactId: result.artifact.id,
|
|
180
|
+
nodes: normalized.nodes,
|
|
181
|
+
chunking: config.effective.chunking,
|
|
182
|
+
}),
|
|
183
|
+
objectHash: normalized.objectHash,
|
|
184
|
+
...(result.tables === undefined || result.tables.length === 0
|
|
185
|
+
? {}
|
|
186
|
+
: { tables: result.tables }),
|
|
187
|
+
...(result.warnings.length === 0 ? {} : { warnings: result.warnings }),
|
|
188
|
+
};
|
|
189
|
+
// A table-bearing parse is deliberately not cached. The cache is a JSON file per
|
|
190
|
+
// artifact, and a 500,000-row table would write hundreds of megabytes there to save
|
|
191
|
+
// a re-read that takes seconds. Rows are exactly reproducible from bytes the build
|
|
192
|
+
// has already read, so the cheap thing to keep is nothing. Nothing is ever written,
|
|
193
|
+
// so nothing can ever be read back missing its tables.
|
|
194
|
+
if (entry.tables === undefined)
|
|
195
|
+
cache.put(key, entry);
|
|
196
|
+
parsed.push(withRules(entry, rulesById));
|
|
197
|
+
handled += 1;
|
|
198
|
+
if (handled % 10 === 0)
|
|
199
|
+
progress.progress('parsing', handled, { unit: 'documents' });
|
|
200
|
+
}
|
|
201
|
+
progress.finish('parsing', handled);
|
|
202
|
+
// One list from here on. Discovery decides an extension has no parser; parsing decides
|
|
203
|
+
// the bytes are not readable text. Both are the same promise to the user, which is
|
|
204
|
+
// that a file the build left out is named rather than silently missing.
|
|
205
|
+
const warnings = [
|
|
206
|
+
...discovery.warnings,
|
|
207
|
+
...fingerprint.warnings,
|
|
208
|
+
// What the parsers said. Discovery reports files left out; these report decisions
|
|
209
|
+
// taken *inside* a file that was kept, which is the other half of the same promise:
|
|
210
|
+
// a heading flattened, a column widened, a sheet not read as a table. Without this
|
|
211
|
+
// every one of them was computed carefully and then dropped (#223).
|
|
212
|
+
...ruleResolution.warnings,
|
|
213
|
+
...parsed.flatMap((entry) => (entry.warnings ?? []).map((warning) => ({
|
|
214
|
+
code: warning.code,
|
|
215
|
+
path: entry.artifact.displayPath,
|
|
216
|
+
message: warning.message,
|
|
217
|
+
}))),
|
|
218
|
+
]
|
|
219
|
+
.map((warning) => ({
|
|
220
|
+
code: warning.code,
|
|
221
|
+
class: warningClass(warning.code),
|
|
222
|
+
path: warning.path,
|
|
223
|
+
message: warning.message,
|
|
224
|
+
}))
|
|
225
|
+
.sort((a, b) => (a.path < b.path ? -1 : a.path > b.path ? 1 : 0));
|
|
226
|
+
// Identity, derived before anything is written so the directory is named correctly.
|
|
227
|
+
const buildId = deriveBuildId({
|
|
228
|
+
formatVersion: 1,
|
|
229
|
+
schemaVersion: nextLock.schema,
|
|
230
|
+
compilerVersion: nextLock.compiler,
|
|
231
|
+
canonicalizationVersion: CANONICALIZATION_VERSION,
|
|
232
|
+
normalizationVersion: NORMALIZATION_VERSION,
|
|
233
|
+
effectiveConfig: config.effective,
|
|
234
|
+
parserVersions: nextLock.parsers,
|
|
235
|
+
ruleResolution: ruleResolution.canonical,
|
|
236
|
+
embeddingProfile: null,
|
|
237
|
+
canonicalRoots: canonicalRoots(parsed),
|
|
238
|
+
});
|
|
239
|
+
/**
|
|
240
|
+
* Reuse only a build that is actually there and actually readable (#251).
|
|
241
|
+
*
|
|
242
|
+
* `state.getBuild` answers from `state.sqlite`, a separate database that stays perfectly
|
|
243
|
+
* intact while the build directory it points at is deleted, truncated, overwritten or
|
|
244
|
+
* left at a catalog schema this version does not read. Trusting the record alone made
|
|
245
|
+
* every one of those permanently unrecoverable: `lorepack build` reported "No changes" and
|
|
246
|
+
* the next read failed exactly as before, including when the failing read's own
|
|
247
|
+
* remediation was to run `lorepack build`.
|
|
248
|
+
*/
|
|
249
|
+
const existing = state.getBuild(buildId);
|
|
250
|
+
const reusable = existing !== null && isBuildReadable(loreDirectory, buildId);
|
|
251
|
+
if (existing !== null && !reusable) {
|
|
252
|
+
// Said out loud rather than rebuilt silently: someone whose build was removed by a
|
|
253
|
+
// disk, a sync tool or an ignore rule should learn that it was.
|
|
254
|
+
progress.diagnostic('warn', `The recorded build ${buildId.slice(0, 17)} cannot be read, so it is being compiled again.`);
|
|
255
|
+
/**
|
|
256
|
+
* Clear the damaged directory, or sealing will decline to replace it.
|
|
257
|
+
*
|
|
258
|
+
* `sealCandidateDirectory` treats an existing id as a no-op, and its reasoning is
|
|
259
|
+
* right for a build that is intact: identical id means identical logical content, so
|
|
260
|
+
* there is nothing to write. It is exactly wrong here. The id still describes the
|
|
261
|
+
* content, and the bytes on disk are no longer that content, so the one case where
|
|
262
|
+
* replacing matters is the one case it refused (#251).
|
|
263
|
+
*
|
|
264
|
+
* Safe because unreadability was just established: there is nothing here to lose that
|
|
265
|
+
* is not already lost, and the candidate that replaces it is validated before it is
|
|
266
|
+
* sealed.
|
|
267
|
+
*/
|
|
268
|
+
rmSync(join(loreDirectory, 'builds', buildId), {
|
|
269
|
+
recursive: true,
|
|
270
|
+
force: true,
|
|
271
|
+
maxRetries: 3,
|
|
272
|
+
});
|
|
273
|
+
}
|
|
274
|
+
if (reusable) {
|
|
275
|
+
const activated = options.activate !== false && state.current()?.buildId !== buildId;
|
|
276
|
+
if (activated)
|
|
277
|
+
state.activate(buildId);
|
|
278
|
+
return {
|
|
279
|
+
buildId,
|
|
280
|
+
created: false,
|
|
281
|
+
activated,
|
|
282
|
+
counts: countsOf(parsed),
|
|
283
|
+
warnings: warnings.length,
|
|
284
|
+
reusedArtifacts: cache.hits,
|
|
285
|
+
rebuiltArtifacts: cache.misses,
|
|
286
|
+
durationMs: now().getTime() - startedAt.getTime(),
|
|
287
|
+
};
|
|
288
|
+
}
|
|
289
|
+
// Index into a candidate directory, outside builds/.
|
|
290
|
+
const candidate = createCandidateDirectory(loreDirectory);
|
|
291
|
+
let sealed = false;
|
|
292
|
+
try {
|
|
293
|
+
await checkpoint(options.signal, { hasActiveBuild: active !== null });
|
|
294
|
+
progress.start('indexing', 'Indexing');
|
|
295
|
+
const db = openWritable(join(candidate.path, 'context.sqlite'));
|
|
296
|
+
try {
|
|
297
|
+
// A fixed timestamp, not the wall clock: a sealed build must carry no
|
|
298
|
+
// operational time. Otherwise two builds of identical content differ in bytes,
|
|
299
|
+
// and `.lorepack` stops being reproducible.
|
|
300
|
+
runMigrations(db, loadMigrations(buildMigrationsDirectory()), () => SEALED_AT);
|
|
301
|
+
const counts = writeCatalog({
|
|
302
|
+
db,
|
|
303
|
+
artifacts: parsed,
|
|
304
|
+
warnings,
|
|
305
|
+
});
|
|
306
|
+
progress.finish('indexing', counts.chunks);
|
|
307
|
+
const manifest = {
|
|
308
|
+
formatVersion: 1,
|
|
309
|
+
buildId,
|
|
310
|
+
projectName: config.config.name,
|
|
311
|
+
compilerVersion: nextLock.compiler,
|
|
312
|
+
schemaVersion: nextLock.schema,
|
|
313
|
+
configurationHash: hashCanonical(config.effective),
|
|
314
|
+
sourceFingerprint: fingerprint.fingerprint,
|
|
315
|
+
canonicalRoots: canonicalRoots(parsed),
|
|
316
|
+
// Declared from what the build contains, not from what the compiler can do. A
|
|
317
|
+
// client that sees `table-query` and finds no tables has been misled about this
|
|
318
|
+
// build, which is worse than not offering the capability.
|
|
319
|
+
capabilities: counts.tables > 0
|
|
320
|
+
? ['lexical-search', 'structured-context', 'table-query']
|
|
321
|
+
: ['lexical-search', 'structured-context'],
|
|
322
|
+
counts,
|
|
323
|
+
warnings: warnings.map((warning) => ({
|
|
324
|
+
code: warning.code,
|
|
325
|
+
message: warning.message,
|
|
326
|
+
...(warning.path === '.' ? {} : { path: warning.path }),
|
|
327
|
+
class: warning.class,
|
|
328
|
+
})),
|
|
329
|
+
// Sealed with the build, so `lorepack inspect exclusions` and Studio can answer after
|
|
330
|
+
// the sources have moved on and after a rollback, without reading a source file.
|
|
331
|
+
// Not an input to `deriveBuildId`: identity is what a build contains, and two
|
|
332
|
+
// builds holding the same artifacts are the same build however the rest was
|
|
333
|
+
// filtered out. Warnings are already outside identity for the same reason.
|
|
334
|
+
exclusions: discovery.exclusions.map((exclusion) => ({
|
|
335
|
+
...exclusion,
|
|
336
|
+
sample: [...exclusion.sample],
|
|
337
|
+
})),
|
|
338
|
+
};
|
|
339
|
+
progress.start('validating', 'Validating');
|
|
340
|
+
const report = await validateCandidate({
|
|
341
|
+
db,
|
|
342
|
+
objects,
|
|
343
|
+
artifacts: parsed,
|
|
344
|
+
manifest: manifest,
|
|
345
|
+
secrets: secretsFromEnv(),
|
|
346
|
+
integrityCheck,
|
|
347
|
+
search: (database, query, limit) => searchCatalog(database, query, limit),
|
|
348
|
+
countRows,
|
|
349
|
+
});
|
|
350
|
+
progress.finish('validating', report.checksRun.length, report.ok ? 'done' : 'failed');
|
|
351
|
+
if (!report.ok) {
|
|
352
|
+
throw new LoreError('LORE_E_BUILD_VALIDATION', `The candidate build failed ${count(report.failures.length, 'check')}:\n${report.failures
|
|
353
|
+
.map((failure) => ` ${failure.check}: ${failure.message}${failure.subject === undefined ? '' : ` (${failure.subject})`}`)
|
|
354
|
+
.join('\n')}`, {
|
|
355
|
+
remediation: 'The active build is unchanged. Fix the reported problems and build again.',
|
|
356
|
+
details: { failures: report.failures },
|
|
357
|
+
});
|
|
358
|
+
}
|
|
359
|
+
buildManifestSchema.parse(manifest);
|
|
360
|
+
writeFileAtomic(join(candidate.path, 'manifest.json'), `${JSON.stringify(manifest, null, 2)}\n`);
|
|
361
|
+
writeFileAtomic(join(candidate.path, 'reports', 'warnings.json'), `${JSON.stringify(warnings, null, 2)}\n`);
|
|
362
|
+
writeFileAtomic(join(candidate.path, 'reports', 'canonical-hashes.json'), `${JSON.stringify({
|
|
363
|
+
algorithm: 'sha256',
|
|
364
|
+
canonicalizationVersion: CANONICALIZATION_VERSION,
|
|
365
|
+
roots: canonicalRoots(parsed),
|
|
366
|
+
}, null, 2)}\n`);
|
|
367
|
+
}
|
|
368
|
+
finally {
|
|
369
|
+
db.close();
|
|
370
|
+
}
|
|
371
|
+
await checkpoint(options.signal, { hasActiveBuild: active !== null });
|
|
372
|
+
progress.start('sealing', 'Sealing');
|
|
373
|
+
const sealedResult = (options.seal ?? sealCandidateDirectory)(candidate, join(loreDirectory, 'builds', buildId));
|
|
374
|
+
if (!sealedResult.sealed && !isBuildReadable(loreDirectory, buildId)) {
|
|
375
|
+
throw new LoreError('LORE_E_INTERNAL', `The build ${buildId} was not sealed and no readable destination exists.`, {
|
|
376
|
+
remediation: 'Check the build directory permissions and build again.',
|
|
377
|
+
});
|
|
378
|
+
}
|
|
379
|
+
sealed = true;
|
|
380
|
+
progress.finish('sealing', 1);
|
|
381
|
+
}
|
|
382
|
+
finally {
|
|
383
|
+
// Any failure or cancellation removes the candidate. builds/ is never touched
|
|
384
|
+
// until the seal, so the active build cannot be disturbed by a failed run.
|
|
385
|
+
if (!sealed)
|
|
386
|
+
discardCandidateDirectory(candidate);
|
|
387
|
+
}
|
|
388
|
+
const counts = countsOf(parsed);
|
|
389
|
+
state.recordBuild({
|
|
390
|
+
buildId,
|
|
391
|
+
state: 'verified',
|
|
392
|
+
createdAt: startedAt.toISOString(),
|
|
393
|
+
counts,
|
|
394
|
+
});
|
|
395
|
+
writeLockfile(config.projectRoot, nextLock);
|
|
396
|
+
let activated = false;
|
|
397
|
+
if (options.activate !== false) {
|
|
398
|
+
progress.start('activating', 'Activating');
|
|
399
|
+
state.activate(buildId, () => now().toISOString());
|
|
400
|
+
progress.finish('activating', 1);
|
|
401
|
+
activated = true;
|
|
402
|
+
}
|
|
403
|
+
return {
|
|
404
|
+
buildId,
|
|
405
|
+
created: true,
|
|
406
|
+
activated,
|
|
407
|
+
counts,
|
|
408
|
+
warnings: warnings.length,
|
|
409
|
+
reusedArtifacts: cache.hits,
|
|
410
|
+
rebuiltArtifacts: cache.misses,
|
|
411
|
+
durationMs: now().getTime() - startedAt.getTime(),
|
|
412
|
+
};
|
|
413
|
+
}
|
|
414
|
+
finally {
|
|
415
|
+
state.close();
|
|
416
|
+
}
|
|
417
|
+
});
|
|
418
|
+
}
|
|
419
|
+
/**
|
|
420
|
+
* Re-reads a source after fingerprinting and binds the bytes handed to the parser to that
|
|
421
|
+
* digest. A source can be edited between the fingerprint and parse stages, so trusting the
|
|
422
|
+
* first hash would record one set of bytes under another set's identity and poison the parse
|
|
423
|
+
* cache. One retry handles an in-flight save; a second mismatch fails the candidate.
|
|
424
|
+
*/
|
|
425
|
+
export function readStableSourceBytes(absolutePath, expectedHash, displayPath) {
|
|
426
|
+
for (let attempt = 0; attempt < 2; attempt += 1) {
|
|
427
|
+
let bytes;
|
|
428
|
+
try {
|
|
429
|
+
bytes = new Uint8Array(readFileSync(absolutePath));
|
|
430
|
+
}
|
|
431
|
+
catch (cause) {
|
|
432
|
+
throw new LoreError('LORE_E_SOURCE_UNREADABLE', `${displayPath} could not be read.`, {
|
|
433
|
+
remediation: 'Check the file permissions, or exclude it in .loreignore.',
|
|
434
|
+
path: displayPath,
|
|
435
|
+
cause,
|
|
436
|
+
});
|
|
437
|
+
}
|
|
438
|
+
if (sha256Hex(bytes) === expectedHash)
|
|
439
|
+
return bytes;
|
|
440
|
+
}
|
|
441
|
+
throw new LoreError('LORE_E_STALE_SOURCES', `${displayPath} changed while the build was reading it.`, {
|
|
442
|
+
remediation: 'Save the source completely, then run `lorepack build` again.',
|
|
443
|
+
path: displayPath,
|
|
444
|
+
});
|
|
445
|
+
}
|
|
446
|
+
function canonicalRoots(parsed) {
|
|
447
|
+
return {
|
|
448
|
+
artifacts: hashRoot(parsed.map((entry) => hashCanonical([entry.artifact.id, entry.artifact.contentHash]))),
|
|
449
|
+
nodes: hashRoot(parsed.flatMap((entry) => entry.nodes.map((node) => node.revisionHash))),
|
|
450
|
+
chunks: hashRoot(parsed.flatMap((entry) => entry.chunks.map((chunk) => chunk.revisionHash))),
|
|
451
|
+
// Every cell, not just the schema. Section 11.4 requires a row change to change the
|
|
452
|
+
// build id, and hashing only the column layout would let two builds with different data
|
|
453
|
+
// share an identity, which is the one thing a build id may never do.
|
|
454
|
+
tables: hashRoot(parsed.flatMap((entry) => (entry.tables ?? []).map((table) => hashCanonical([
|
|
455
|
+
table.tableId,
|
|
456
|
+
table.columns.map((column) => [column.name, column.type, column.nullable]),
|
|
457
|
+
table.rows,
|
|
458
|
+
])))),
|
|
459
|
+
objects: hashRoot(parsed.map((entry) => entry.objectHash)),
|
|
460
|
+
};
|
|
461
|
+
}
|
|
462
|
+
function countsOf(parsed) {
|
|
463
|
+
const tables = parsed.flatMap((entry) => entry.tables ?? []);
|
|
464
|
+
return {
|
|
465
|
+
artifacts: parsed.length,
|
|
466
|
+
nodes: parsed.reduce((sum, entry) => sum + entry.nodes.length, 0),
|
|
467
|
+
chunks: parsed.reduce((sum, entry) => sum + entry.chunks.length, 0),
|
|
468
|
+
tables: tables.length,
|
|
469
|
+
// Counted from the parse rather than read back from SQLite, so this agrees with the
|
|
470
|
+
// manifest on a rebuild that reused an existing build directory and wrote no rows.
|
|
471
|
+
tableRows: tables.reduce((sum, table) => sum + table.rows.length, 0),
|
|
472
|
+
};
|
|
473
|
+
}
|
|
474
|
+
/**
|
|
475
|
+
* A parsed artifact with its declared rules applied.
|
|
476
|
+
*
|
|
477
|
+
* Parsers leave every artifact neutral on purpose, with a comment forbidding them from
|
|
478
|
+
* inferring status or authority from content: that would be inventing truth. The declaration
|
|
479
|
+
* is the user's, and this is where it lands, after parsing and before indexing.
|
|
480
|
+
*
|
|
481
|
+
* Applied on the cached path too. The cache key covers the resolution, so a hit already agrees
|
|
482
|
+
* about the rules, but reapplying costs nothing and means the rule values in a build come from
|
|
483
|
+
* one place rather than from whichever path an artifact happened to take.
|
|
484
|
+
*/
|
|
485
|
+
function withRules(entry, rulesById) {
|
|
486
|
+
const rule = rulesById.get(entry.artifact.id);
|
|
487
|
+
if (rule === undefined)
|
|
488
|
+
return entry;
|
|
489
|
+
return {
|
|
490
|
+
...entry,
|
|
491
|
+
artifact: {
|
|
492
|
+
...entry.artifact,
|
|
493
|
+
status: rule.status,
|
|
494
|
+
authority: rule.authority,
|
|
495
|
+
supersedes: [...rule.supersedes],
|
|
496
|
+
},
|
|
497
|
+
};
|
|
498
|
+
}
|
|
499
|
+
//# sourceMappingURL=build.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"build.js","sourceRoot":"","sources":["../../src/services/build.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { LocalStateStore } from '@lorepack/backend-local';
|
|
2
|
+
import type { BuildSnapshot } from '@lorepack/compiler';
|
|
3
|
+
import { assertBuildId, type BuildId, type BuildSummary } from '@lorepack/core';
|
|
4
|
+
/**
|
|
5
|
+
* Reading sealed builds: history, resolution of a short id, and the snapshot the diff
|
|
6
|
+
* engine works on.
|
|
7
|
+
*
|
|
8
|
+
* Everything here reads build data only. Nothing re-parses a source, which is what lets
|
|
9
|
+
* `lorepack diff` and `lorepack rollback` work in a project whose source directory has been
|
|
10
|
+
* deleted, and what makes both operations instant.
|
|
11
|
+
*/
|
|
12
|
+
export declare function openStateStore(loreDirectory: string): LocalStateStore;
|
|
13
|
+
/**
|
|
14
|
+
* Resolves a full id or an unambiguous prefix.
|
|
15
|
+
*
|
|
16
|
+
* An ambiguous prefix lists the candidates rather than picking one. Silently choosing
|
|
17
|
+
* would mean activating a build the user did not name.
|
|
18
|
+
*/
|
|
19
|
+
export declare function resolveBuildId(builds: readonly BuildSummary[], reference: string): BuildId;
|
|
20
|
+
/**
|
|
21
|
+
* The build a rollback returns to: the newest activatable one that is not already live.
|
|
22
|
+
*
|
|
23
|
+
* One definition, used by `lorepack rollback` and by the Studio endpoint behind the same button,
|
|
24
|
+
* because two definitions is how a terminal and a browser end up returning to different
|
|
25
|
+
* builds from the same history.
|
|
26
|
+
*/
|
|
27
|
+
export declare function previousBuild(builds: readonly BuildSummary[], active: BuildId | null): BuildId;
|
|
28
|
+
export declare function buildDirectory(loreDirectory: string, buildId: BuildId): string;
|
|
29
|
+
/** Reads the canonical records a diff compares, straight out of the sealed build. */
|
|
30
|
+
export declare function readSnapshot(loreDirectory: string, buildId: BuildId): BuildSnapshot;
|
|
31
|
+
/**
|
|
32
|
+
* Pre-flight before a pointer change: the build exists, passed validation, its database
|
|
33
|
+
* opens, and its integrity check passes.
|
|
34
|
+
*
|
|
35
|
+
* Activation is cheap, but activating a corrupt build is not, so the check happens before
|
|
36
|
+
* the pointer moves rather than at the first request that fails.
|
|
37
|
+
*/
|
|
38
|
+
export declare function assertActivatable(loreDirectory: string, build: BuildSummary): void;
|
|
39
|
+
export { assertBuildId };
|
|
40
|
+
//# sourceMappingURL=builds.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"builds.d.ts","sourceRoot":"","sources":["../../src/services/builds.ts"],"names":[],"mappings":"AAEA,OAAO,EAGL,eAAe,EAIhB,MAAM,yBAAyB,CAAC;AACjC,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACxD,OAAO,EACL,aAAa,EACb,KAAK,OAAO,EACZ,KAAK,YAAY,EAMlB,MAAM,gBAAgB,CAAC;AAExB;;;;;;;GAOG;AAEH,wBAAgB,cAAc,CAAC,aAAa,EAAE,MAAM,GAAG,eAAe,CAOrE;AAED;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,MAAM,EAAE,SAAS,YAAY,EAAE,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAkC1F;AAED;;;;;;GAMG;AACH,wBAAgB,aAAa,CAAC,MAAM,EAAE,SAAS,YAAY,EAAE,EAAE,MAAM,EAAE,OAAO,GAAG,IAAI,GAAG,OAAO,CAa9F;AAED,wBAAgB,cAAc,CAAC,aAAa,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,GAAG,MAAM,CAE9E;AAED,qFAAqF;AACrF,wBAAgB,YAAY,CAAC,aAAa,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,GAAG,aAAa,CAsGnF;AAED;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAAC,aAAa,EAAE,MAAM,EAAE,KAAK,EAAE,YAAY,GAAG,IAAI,CA4ClF;AAED,OAAO,EAAE,aAAa,EAAE,CAAC"}
|