Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[do-not-review] strong init as the main #554

Closed
wants to merge 4 commits into from
Closed
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
70 changes: 42 additions & 28 deletions client/packages/cli/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -410,8 +410,8 @@ function printDotEnvInfo(source, appId) {
const otherEnvs = Object.values(rest);
otherEnvs.sort();
const otherEnvStr = otherEnvs.map((x) => " " + chalk.green(x)).join("\n");
console.log(`Alternative names: \n${otherEnvStr}`);
console.log(terminalLink("Dashboard", appDashUrl(appId)));
console.log(`Alternative names: \n${otherEnvStr}\n`);
console.log(terminalLink("Dashboard", appDashUrl(appId)) + "\n");
}
}

Expand Down Expand Up @@ -1530,7 +1530,7 @@ function generateSchemaTypescriptFile(id, schema, title, instantModuleName) {

const entitiesObjCode = `{\n${entitiesEntriesCode}\n}`;

const linksEntriesCode = Object.fromEntries(
const linksEntries = Object.fromEntries(
sortedEntries(schema.refs).map(([_name, config]) => {
const [, fe, flabel] = config["forward-identity"];
const [, re, rlabel] = config["reverse-identity"];
Expand All @@ -1552,38 +1552,52 @@ function generateSchemaTypescriptFile(id, schema, title, instantModuleName) {
];
}),
);
const linksEntriesCode = JSON.stringify(linksEntries, null, " ");

return `
// ${appDashUrl(id)}
// Docs: https://www.instantdb.com/docs/schema

import { i } from "${instantModuleName ?? "@instantdb/core"}";

const graph = i.graph(
${
Object.keys(schema.blobs).length === 1 &&
Object.keys(schema.blobs)[0] === "$users"
const etypes = Object.keys(schema.blobs);
const hasOnlyUserTable = etypes.length === 1 && etypes[0] === "$users";
const entitiesComment = hasOnlyUserTable
? `
// This section lets you define entities: think \`posts\`, \`comments\`, etc
// Take a look at the docs to learn more:
// https://www.instantdb.com/docs/schema#defining-entities
`.trim()
: ""
}
${indentLines(entitiesObjCode, 1)},
${
Object.keys(schema.refs).length === 0
: "";
const hasNoLinks = Object.keys(linksEntries).length === 0;
const linksComment = hasNoLinks
? `
// You can define links here.
// For example, if \`posts\` should have many \`comments\`.
// More in the docs:
// https://www.instantdb.com/docs/schema#defining-links
`.trim()
: ""
}
${indentLines(JSON.stringify(linksEntriesCode, null, " "), 1)}
);
// You can define links here.
// For example, if \`posts\` should have many \`comments\`.
// More in the docs:
// https://www.instantdb.com/docs/schema#defining-links
`.trim()
: "";

const roomsComment = `
// If you use presence, you can define a room schema here
// https://www.instantdb.com/docs/schema#defining-rooms
`.trim();

return `
// Docs: https://www.instantdb.com/docs/schema

import { i } from "${instantModuleName ?? "@instantdb/core"}";

const _schema = i.schema({
${entitiesComment}
entities: ${entitiesObjCode},
${linksComment}
links: ${linksEntriesCode},
${roomsComment}
rooms: {}
});

// This helps Typescript display nicer intellisense
type _AppSchema = typeof _schema;
interface AppSchema extends _AppSchema {}
const schema: AppSchema = _schema;

export default graph;
export { type AppSchema }
export default schema;
`;
}
19 changes: 8 additions & 11 deletions client/packages/core/__tests__/src/schema.test.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import { test } from "vitest";

import { i } from "../../src";
import type { InstaQLQueryResult } from "../../src/queryTypes";
import type { InstaQLResult } from "../../src/queryTypes";

test("runs without exception", () => {
const graph = i.graph(
{
const schema = i.schema({
entities: {
users: i.entity({
name: i.string(),
email: i.string().indexed().unique(),
Expand All @@ -23,7 +23,7 @@ test("runs without exception", () => {
body: i.string(),
}),
},
{
links: {
usersPosts: {
forward: {
on: "users",
Expand Down Expand Up @@ -73,7 +73,8 @@ test("runs without exception", () => {
},
},
},
);
rooms: {},
});

const demoQuery = {
users: {
Expand All @@ -88,7 +89,7 @@ test("runs without exception", () => {
},
};

type Graph = typeof graph;
type Graph = typeof schema;

// Explore derived types
type Test1 = Graph["entities"]["users"]["links"]["_friends"]["entityName"];
Expand All @@ -103,11 +104,7 @@ test("runs without exception", () => {
// - referrer is NOT an array (because cardinality is 'one')
// - posts is not an array (because `$first`)
const queryResult: DemoQueryResult = null as any;
type DemoQueryResult = InstaQLQueryResult<
Graph["entities"],
typeof demoQuery,
true
>;
type DemoQueryResult = InstaQLResult<Graph, typeof demoQuery>;
queryResult?.users[0].friends[0]._friends[0].bio;
queryResult?.users[0].posts[0].author?.junk;
});
56 changes: 26 additions & 30 deletions client/packages/core/src/schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,37 +13,19 @@ import {
// ==========
// API


/**
* Accepts entities and links and merges them into a single graph definition.
* @deprecated
* `i.graph` is deprecated. Use `i.schema` instead.
*
* @see https://instantdb.com/docs/schema#defining-entities
* @example
* export default i.graph(
* {
* posts: i.entity({
* title: i.string(),
* body: i.string(),
* }),
* comments: i.entity({
* body: i.string(),
* }),
* },
* {
* postsComments: {
* forward: {
* on: "posts",
* has: "many",
* label: "comments",
* },
* reverse: {
* on: "comments",
* has: "one",
* label: "post",
* },
* },
* },
* );
* // Before
* i.graph(entities, links).withRoomSchema<RoomType>();
*
* // After
* i.schema({ entities, links, rooms })
*
* @see
* https://instantdb.com/docs/schema
*/
function graph<
EntitiesWithoutLinks extends EntitiesDef,
Expand Down Expand Up @@ -152,8 +134,22 @@ type LinksIndex = Record<
Record<string, Record<string, { entityName: string; cardinality: string }>>
>;

/**
* TODO
/**
* Lets you define a schema for your database.
*
* You can define entities, links between entities, and if you use
* presence, you can define rooms.
*
* You can push this schema to your database with the CLI,
* or use it inside `init_experimental`, to get typesafety and autocompletion.
*
* @see https://instantdb.com/docs/schema
* @example
* i.schema({
* entities: { },
* links: { },
* rooms: { }
* });
*/
function schema<
EntitiesWithoutLinks extends EntitiesDef,
Expand Down
11 changes: 6 additions & 5 deletions client/sandbox/cli-nodejs/instant.schema.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { i } from "@instantdb/core";

const graph = i.graph(
{
const schema = i.schema({
entities: {
authors: i.entity({
name: i.any(),
userId: i.any(),
Expand All @@ -14,7 +14,7 @@ const graph = i.graph(
label: i.any(),
}),
},
{
links: {
authorsPosts: {
forward: {
on: "authors",
Expand All @@ -40,6 +40,7 @@ const graph = i.graph(
},
},
},
);
rooms: {},
});

export default graph;
export default schema;
49 changes: 26 additions & 23 deletions client/sandbox/strong-init-vite/instant.schema.ts
Original file line number Diff line number Diff line change
@@ -1,33 +1,36 @@
// Docs: https://www.instantdb.com/docs/schema

import { i } from "@instantdb/react";

const _graph = i.graph(
{
messages: i.entity({
content: i.string(),
}),
const _schema = i.schema({
// This section lets you define entities: think `posts`, `comments`, etc
// Take a look at the docs to learn more:
// https://www.instantdb.com/docs/schema#defining-entities
entities: {
$users: i.entity({
email: i.string().unique().indexed(),
}),
},
{
messageCreator: {
forward: {
on: "messages",
has: "one",
label: "creator",
},
reverse: {
on: "$users",
has: "many",
label: "createdMessages",
},
// You can define links here.
// For example, if `posts` should have many `comments`.
// More in the docs:
// https://www.instantdb.com/docs/schema#defining-links
links: {},
// If you use presence, you can define a room schema here
// https://www.instantdb.com/docs/schema#defining-rooms
rooms: {
chat: {
presence: i.entity({
nickname: i.string(),
}),
},
},

);
});

type _Graph = typeof _graph;
// This helps Typescript display nicer intellisense
type _AppSchema = typeof _schema;
interface AppSchema extends _AppSchema {}
const schema: AppSchema = _schema;

export interface Graph extends _Graph {};
const graph: Graph = _graph;
export default graph;
export { type AppSchema };
export default schema;
Loading