mirror of
https://github.com/callstack/agent-device.git
synced 2026-09-14 20:06:34 +08:00
d8a7d03faf
* refactor: route application lifecycle through runtime facts Moves the canonical `open`, `prepare`, `close` and internal `runtime` descriptors behind package-owned lifecycle bindings admitted from device runtime facts, while daemon request/session policy and public response construction stay put. Based on main, which already carries the boot unit, the parametrized cutover gate and the apps unit. Readiness is package-owned there, so the Apple and Android bindings call ensureAppleReady/ensureAndroidReady rather than a root readiness bag; ensureAppleReady gained an onColdBootStart hook so open keeps warming the runner cache in parallel with a cold boot, and a narrow markBooted port publishes readiness' fresh observation so a flow still makes one simctl listing. Cutover rows take R24-R27, clear of the accepted catalog and the sibling install stack, and cutoverTableDefects rejects a duplicate rule id. Two defects this unit introduced are fixed here rather than shipped: `open <app> <url>` dropped the URL on a first open, and test-IME activation was first fatal on an unobtainable helper and then over-caught. Helper unavailability is a typed non-activation outcome now; fence, lock and post-record failures propagate. The duplication the unit had accumulated is gone: one runtime-admission module instead of five per-command copies, one direct-lifecycle binding factory instead of six hand-rolled packages, one transport-hint predicate, one session finalization path, and no identity-wrapper module. * fix: allocate lifecycle cutover rows after deployment * chore: preserve lifecycle union reconstruction * fix: reconcile lifecycle runtime stack * refactor: tighten lifecycle runtime topology * refactor: remove superseded runtime adapters * fix: preserve stacked runtime cutovers * test: preserve migrated runtime ownership * test: move Android deployment retry ownership * test: extract runtime hint fixtures * fix: preserve lifecycle stack invariants * fix: complete lifecycle runtime cutover * fix: remove lifecycle cutover residue
67 lines
2.3 KiB
TypeScript
67 lines
2.3 KiB
TypeScript
import { parseSync } from 'oxc-parser';
|
|
import { propertyName, visitAst } from './cutover-policy-ast.ts';
|
|
import { lineOf, type CutoverAstNode } from './runtime-command-cutover-ast.ts';
|
|
import type { UnruledViolation } from './runtime-command-cutover-model.ts';
|
|
|
|
const COMMAND_DESCRIPTOR_MODULE = 'src/core/command-descriptor/registry.ts';
|
|
|
|
/** A device-runtime cutover must remove the command from the legacy dispatch projection. */
|
|
export function retiredDispatchProjectionViolations(
|
|
sources: ReadonlyMap<string, string>,
|
|
command: string,
|
|
): UnruledViolation[] {
|
|
const source = sources.get(COMMAND_DESCRIPTOR_MODULE);
|
|
if (source === undefined) {
|
|
return [
|
|
{
|
|
file: COMMAND_DESCRIPTOR_MODULE,
|
|
line: 1,
|
|
message: `${command} command descriptor module is missing`,
|
|
},
|
|
];
|
|
}
|
|
const program = parseSync(COMMAND_DESCRIPTOR_MODULE, source).program as CutoverAstNode;
|
|
let descriptor: CutoverAstNode | undefined;
|
|
visitAst(program, (node) => {
|
|
if (node.type !== 'ObjectExpression') return;
|
|
const properties = objectProperties(node);
|
|
const name = properties.find((property) => propertyName(property.key) === 'name');
|
|
if (literalString(name?.value) !== command) return;
|
|
if (!properties.some((property) => propertyName(property.key) === 'platformExecution')) return;
|
|
descriptor = node;
|
|
});
|
|
if (descriptor === undefined) {
|
|
return [
|
|
{
|
|
file: COMMAND_DESCRIPTOR_MODULE,
|
|
line: 1,
|
|
message: `${command} command descriptor is missing`,
|
|
},
|
|
];
|
|
}
|
|
const dispatch = objectProperties(descriptor).find(
|
|
(property) => propertyName(property.key) === 'dispatch',
|
|
);
|
|
return dispatch === undefined
|
|
? []
|
|
: [
|
|
{
|
|
file: COMMAND_DESCRIPTOR_MODULE,
|
|
line: lineOf(source, dispatch),
|
|
message: `${command} command still projects into the retired legacy dispatcher`,
|
|
},
|
|
];
|
|
}
|
|
|
|
function objectProperties(node: CutoverAstNode): CutoverAstNode[] {
|
|
return Array.isArray(node.properties) ? (node.properties as CutoverAstNode[]) : [];
|
|
}
|
|
|
|
function literalString(node: unknown): string | undefined {
|
|
if (node === null || typeof node !== 'object') return undefined;
|
|
const candidate = node as CutoverAstNode;
|
|
return candidate.type === 'Literal' && typeof candidate.value === 'string'
|
|
? candidate.value
|
|
: undefined;
|
|
}
|