Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@
`ember test --path dist --filter "some text that appears in module name or test name"`
Note that the filter is matched against the module name and test name, not the file name! Try to avoid using pipe characters in the filter, since they can confuse auto-approval tool use filters set up by the user.
- run `pnpm lint` in this directory to lint changes made to this package
- run `pnpm lint:fix` directly in this directory to apply fixes for lint failures made to this package that can be automatically fixed.

#### Iterating on host tests with the Chrome MCP server

Expand Down Expand Up @@ -96,6 +97,7 @@
Make sure not to commit `.only` to source control
- make sure to kill previously running realm-server tests if they are still running before starting a new test run.
- run `pnpm lint` directly in this directory to lint changes made to this package
- run `pnpm lint:fix` directly in this directory to apply fixes for lint failures made to this package that can be automatically fixed.

### packages/postgres
- If you need to make a database migration use `pnpm create migration_name` to create a migration file so that the correct date timestamp prefix will be added to the file name. Then implement the migration inside the newly created file.
Expand All @@ -106,7 +108,8 @@
### packages/runtime-common

- Functionality is tested via host and/or realm-server tests
- run `pnpm lint` directly in packages/host or directly in packages/realm-server to lint for changes made in this package. This package will be linted since both packages/host and package/realm-server consume this package.
- run `pnpm lint` directly in this directory to lint changes made to this package
- run `pnpm lint:js:fix` directly in this directory to apply fixes for js lint failures made to this package that can be automatically fixed.

## PR Instructions

Expand Down
153 changes: 153 additions & 0 deletions packages/realm-server/tests/indexing-test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2036,6 +2036,159 @@ module(basename(__filename), function () {
);
});

// remove this once we have a query based relationship invalidation strategy
test('does not capture deps from query-backed relationships', async function (assert) {
await realm.write(
'query-rel-target.gts',
`
import { CardDef, Component, contains, field } from "https://cardstack.com/base/card-api";
import StringField from "https://cardstack.com/base/string";

export class QueryRelTarget extends CardDef {
@field cardTitle = contains(StringField);

static embedded = class Embedded extends Component<typeof this> {
<template>
<span><@fields.cardTitle /></span>
</template>
}
}
`,
);

await realm.write(
'query-rel-consumer.gts',
`
import { CardDef, Component, contains, field, linksTo, linksToMany } from "https://cardstack.com/base/card-api";
import StringField from "https://cardstack.com/base/string";

export class QueryRelConsumer extends CardDef {
@field cardTitle = contains(StringField);
@field favorite = linksTo(() => CardDef, {
query: {
filter: {
eq: {
cardTitle: 'target',
},
},
},
});
@field matches = linksToMany(() => CardDef, {
query: {
filter: {
eq: {
cardTitle: 'target',
},
},
page: {
size: 10,
number: 0,
},
},
});

static isolated = class Isolated extends Component<typeof this> {
<template>
<@fields.favorite />
<@fields.matches />
</template>
}
}
`,
);

await realm.write(
'query-rel-target-1.json',
JSON.stringify({
data: {
attributes: { cardTitle: 'target' },
meta: {
adoptsFrom: {
module: './query-rel-target',
name: 'QueryRelTarget',
},
},
},
} as LooseSingleCardDocument),
);

await realm.write(
'query-rel-consumer-1.json',
JSON.stringify({
data: {
attributes: { cardTitle: 'consumer' },
meta: {
adoptsFrom: {
module: './query-rel-consumer',
name: 'QueryRelConsumer',
},
},
},
} as LooseSingleCardDocument),
);

let queryConsumerDoc = await realm.realmIndexQueryEngine.cardDocument(
new URL(`${testRealm}query-rel-consumer-1`),
{ loadLinks: true },
);
if (queryConsumerDoc?.type === 'doc') {
let relationships = queryConsumerDoc.doc.data.relationships ?? {};
let favorite = relationships.favorite as
| {
links?: Record<string, string | null>;
data?: { type: string; id: string } | null;
}
| undefined;
let matches = relationships.matches as
| {
links?: Record<string, string | null>;
data?: { type: string; id: string }[];
}
| undefined;
assert.strictEqual(
typeof favorite?.links?.search,
'string',
'query linksTo relationship is present',
);
assert.deepEqual(
favorite?.data,
{
type: 'card',
id: `${testRealm}query-rel-target-1`,
},
'query linksTo relationship contains matched target',
);
assert.strictEqual(
typeof matches?.links?.search,
'string',
'query linksToMany relationship is present',
);
assert.deepEqual(
matches?.data,
[
{
type: 'card',
id: `${testRealm}query-rel-target-1`,
},
],
'query linksToMany relationship contains matched targets',
);
} else {
assert.ok(false, 'expected query-backed consumer document');
}

let deps = await depsFor(`${testRealm}query-rel-consumer-1.json`);
assert.true(deps.length > 0, 'consumer instance has deps');
assert.notOk(
deps.includes(`${testRealm}query-rel-target-1.json`),
'query-backed relationship target is not tracked as a dependency',
);
assert.notOk(
deps.includes(`${testRealm}query-rel-target`),
'query-backed relationship target module is not tracked as a dependency',
);
});

test('collects glimmer scoped CSS deps from first-degree and second-degree relationship instances', async function (assert) {
await realm.write(
'second-rel.gts',
Expand Down
5 changes: 5 additions & 0 deletions packages/runtime-common/index-runner/card-indexer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,10 @@ export async function performCardIndexing({
),
);

let queryFieldPaths = dependencyResolver.extractQueryFieldRelationshipPaths(
resource,
(renderResult?.serialized?.data as CardResource | undefined) ?? null,
);
let relationshipDeps = new Set<string>([
...dependencyResolver.extractDirectRelationshipDeps(
resource,
Expand All @@ -164,6 +168,7 @@ export async function performCardIndexing({
...dependencyResolver.extractSearchDocRelationshipDeps(
renderError.searchData ?? null,
instanceURL,
queryFieldPaths,
),
]);
renderError.error.deps.push(...relationshipDeps);
Expand Down
Loading