├── .git-blame-ignore-revs ├── .github ├── actions │ └── elastic-beanstalk │ │ ├── .yarnrc.yml │ │ ├── README.md │ │ ├── action.yml │ │ ├── bin │ │ └── index.js │ │ ├── package.json │ │ ├── src │ │ ├── index.ts │ │ └── main.ts │ │ ├── tsconfig.json │ │ └── yarn.lock └── workflows │ ├── clojure.yml │ └── js.yml ├── .gitignore ├── LICENSE.md ├── README.md ├── client ├── .editorconfig ├── .prettierrc ├── Makefile ├── README.md ├── package.json ├── packages │ ├── admin │ │ ├── .npmignore │ │ ├── README.md │ │ ├── package.json │ │ ├── src │ │ │ ├── index.ts │ │ │ └── version.js │ │ └── tsconfig.json │ ├── cli │ │ ├── README.md │ │ ├── bin │ │ │ └── index.js │ │ ├── package.json │ │ ├── src │ │ │ ├── index.js │ │ │ ├── toggle.ts │ │ │ ├── util │ │ │ │ ├── fs.ts │ │ │ │ └── packageManager.js │ │ │ └── version.js │ │ └── tsconfig.json │ ├── core │ │ ├── .npmignore │ │ ├── README.md │ │ ├── __example__ │ │ │ ├── standalone.esm.html │ │ │ └── standalone.umd.html │ │ ├── __tests__ │ │ │ └── src │ │ │ │ ├── Reactor.test.js │ │ │ │ ├── data │ │ │ │ ├── movies │ │ │ │ │ ├── attrs.json │ │ │ │ │ └── triples.json │ │ │ │ └── zeneca │ │ │ │ │ ├── attrs.json │ │ │ │ │ └── triples.json │ │ │ │ ├── datalog.test.js │ │ │ │ ├── instaml.test.js │ │ │ │ ├── instaql.bench.js │ │ │ │ ├── instaql.test.js │ │ │ │ ├── instaqlInference.test.js │ │ │ │ ├── schema.test.ts │ │ │ │ ├── store.test.js │ │ │ │ └── utils │ │ │ │ └── object.test.js │ │ ├── package.json │ │ ├── src │ │ │ ├── InMemoryStorage.js │ │ │ ├── IndexedDBStorage.js │ │ │ ├── Reactor.js │ │ │ ├── StorageAPI.ts │ │ │ ├── WindowNetworkListener.js │ │ │ ├── attrTypes.ts │ │ │ ├── authAPI.ts │ │ │ ├── clientTypes.ts │ │ │ ├── coreTypes.ts │ │ │ ├── datalog.js │ │ │ ├── devtool.ts │ │ │ ├── helperTypes.ts │ │ │ ├── index.ts │ │ │ ├── instaml.js │ │ │ ├── instaql.js │ │ │ ├── instatx.ts │ │ │ ├── model │ │ │ │ └── instaqlResult.js │ │ │ ├── presence.ts │ │ │ ├── queryTypes.ts │ │ │ ├── rulesTypes.ts │ │ │ ├── sanityCheckQueries.ts │ │ │ ├── schema.ts │ │ │ ├── schemaTypes.ts │ │ │ ├── store.js │ │ │ ├── utils │ │ │ │ ├── Deferred.js │ │ │ │ ├── PersistedObject.js │ │ │ │ ├── error.ts │ │ │ │ ├── fetch.ts │ │ │ │ ├── flags.ts │ │ │ │ ├── linkIndex.ts │ │ │ │ ├── log.ts │ │ │ │ ├── object.js │ │ │ │ ├── pick.js │ │ │ │ ├── uuid.ts │ │ │ │ └── weakHash.ts │ │ │ └── version.js │ │ ├── tsconfig.json │ │ └── vite.config.ts │ ├── platform │ │ ├── README.md │ │ ├── __tests__ │ │ │ └── src │ │ │ │ ├── perms.test.ts │ │ │ │ ├── schema.test.ts │ │ │ │ └── test.ts │ │ ├── package.json │ │ ├── src │ │ │ ├── ProgressPromise.ts │ │ │ ├── api.ts │ │ │ ├── crypto.ts │ │ │ ├── index.ts │ │ │ ├── oauth.ts │ │ │ ├── oauthCommon.ts │ │ │ ├── perms.ts │ │ │ ├── schema.ts │ │ │ ├── serverOAuth.ts │ │ │ └── version.js │ │ ├── tsconfig.json │ │ └── vite.config.ts │ ├── react-native │ │ ├── .npmignore │ │ ├── README.md │ │ ├── package.json │ │ ├── src │ │ │ ├── NetworkListener.js │ │ │ ├── Storage.js │ │ │ ├── Storage.native.js │ │ │ ├── cli.ts │ │ │ ├── index.ts │ │ │ └── version.js │ │ ├── tsconfig.json │ │ └── tsconfig.module.json │ └── react │ │ ├── .npmignore │ │ ├── README.md │ │ ├── __example__ │ │ ├── standalone.esm.html │ │ └── standalone.umd.html │ │ ├── package.json │ │ ├── src │ │ ├── Cursors.tsx │ │ ├── InstantReactAbstractDatabase.ts │ │ ├── InstantReactRoom.ts │ │ ├── InstantReactWebDatabase.ts │ │ ├── index.ts │ │ ├── init.ts │ │ ├── useQuery.ts │ │ ├── useTimeout.ts │ │ └── version.js │ │ ├── tsconfig.json │ │ └── vite.config.ts ├── pnpm-lock.yaml ├── pnpm-workspace.yaml ├── sandbox │ ├── admin-sdk-express │ │ ├── .env.example │ │ ├── README.md │ │ ├── package.json │ │ └── src │ │ │ ├── circle_blue.jpg │ │ │ ├── index.ts │ │ │ └── with-schema.ts │ ├── cli-nodejs │ │ ├── .env.example │ │ ├── README.md │ │ ├── package.json │ │ ├── src │ │ │ └── db │ │ │ │ ├── instant.perms.ts │ │ │ │ └── instant.schema.ts │ │ └── tsconfig.json │ ├── react-native-expo │ │ ├── .env.example │ │ ├── .gitignore │ │ ├── README.md │ │ ├── app.json │ │ ├── app │ │ │ ├── _layout.js │ │ │ ├── config.js │ │ │ ├── index.js │ │ │ └── play │ │ │ │ ├── authhello.js │ │ │ │ ├── colors-schema.js │ │ │ │ ├── colors.js │ │ │ │ ├── expo-auth-session.js │ │ │ │ └── litoe.js │ │ ├── assets │ │ │ ├── adaptive-icon.png │ │ │ ├── favicon.png │ │ │ ├── icon.png │ │ │ └── splash.png │ │ ├── babel.config.js │ │ ├── instant.perms.ts │ │ ├── instant.schema.ts │ │ ├── metro.config.js │ │ ├── nativewind-env.d.ts │ │ ├── package.json │ │ ├── postcss.config.js │ │ ├── tailwind.config.js │ │ └── tsconfig.json │ ├── react-nextjs │ │ ├── .env.example │ │ ├── .gitignore │ │ ├── README.md │ │ ├── app │ │ │ ├── layout.tsx │ │ │ └── play │ │ │ │ ├── app-router-login │ │ │ │ └── page.tsx │ │ │ │ ├── check-admin-cache │ │ │ │ └── page.tsx │ │ │ │ ├── large-query-perf │ │ │ │ └── page.tsx │ │ │ │ └── route-hydration │ │ │ │ └── [[...slug]] │ │ │ │ └── page.tsx │ │ ├── components │ │ │ ├── EphemeralAppPage.tsx │ │ │ └── Login.jsx │ │ ├── config.ts │ │ ├── imgs │ │ │ ├── circle_blue.jpg │ │ │ ├── circle_green.jpg │ │ │ ├── circle_red.jpg │ │ │ ├── square_blue.jpg │ │ │ ├── square_green.jpg │ │ │ ├── square_red.jpg │ │ │ ├── triangle_blue.jpg │ │ │ ├── triangle_green.jpg │ │ │ └── triangle_red.jpg │ │ ├── lib │ │ │ └── files.ts │ │ ├── next.config.js │ │ ├── package.json │ │ ├── pages │ │ │ ├── _app.tsx │ │ │ ├── index.tsx │ │ │ ├── patterns │ │ │ │ └── split-attributes.tsx │ │ │ ├── platform │ │ │ │ └── oauth-landing.tsx │ │ │ └── play │ │ │ │ ├── authhello.tsx │ │ │ │ ├── authsync.tsx │ │ │ │ ├── avatar.tsx │ │ │ │ ├── checkins.tsx │ │ │ │ ├── clerk.tsx │ │ │ │ ├── color.tsx │ │ │ │ ├── connect-status.tsx │ │ │ │ ├── convert.tsx │ │ │ │ ├── cursors.tsx │ │ │ │ ├── customauth.tsx │ │ │ │ ├── dev-devtool.tsx │ │ │ │ ├── ephemeral-counts.tsx │ │ │ │ ├── ephemeral-demo.tsx │ │ │ │ ├── ephemeral.tsx │ │ │ │ ├── fields.tsx │ │ │ │ ├── flicker.tsx │ │ │ │ ├── googleloginbutton.tsx │ │ │ │ ├── hazelcast-broadcast.tsx │ │ │ │ ├── hazelcast.tsx │ │ │ │ ├── hello-world-blank.tsx │ │ │ │ ├── join-room-set-presence-core.tsx │ │ │ │ ├── join-room-set-presence.tsx │ │ │ │ ├── missing-attrs.tsx │ │ │ │ ├── notandnil.tsx │ │ │ │ ├── oauthlogin.tsx │ │ │ │ ├── operators.tsx │ │ │ │ ├── pagination.tsx │ │ │ │ ├── patch.tsx │ │ │ │ ├── pending-transactions.tsx │ │ │ │ ├── platform-sdk-demo.tsx │ │ │ │ ├── presence-arrays.tsx │ │ │ │ ├── query-like.tsx │ │ │ │ ├── query-once-toggle.tsx │ │ │ │ ├── query-once.tsx │ │ │ │ ├── refresh-batch.tsx │ │ │ │ ├── ruleParams.tsx │ │ │ │ ├── save-undefined.tsx │ │ │ │ ├── schema-hot-reloading.tsx │ │ │ │ ├── sign-in-with-apple.tsx │ │ │ │ ├── stickers.tsx │ │ │ │ ├── storage-v2.tsx │ │ │ │ ├── storage.tsx │ │ │ │ ├── stress.tsx │ │ │ │ ├── strong-todos.tsx │ │ │ │ ├── todo.jsx │ │ │ │ └── use-query.tsx │ │ ├── postcss.config.js │ │ ├── public │ │ │ ├── favicon.ico │ │ │ └── vercel.svg │ │ ├── styles │ │ │ └── globals.css │ │ ├── tailwind.config.js │ │ └── tsconfig.json │ ├── strong-init-vite │ │ ├── .env.example │ │ ├── .gitignore │ │ ├── README.md │ │ ├── eslint.config.js │ │ ├── index.html │ │ ├── instant.perms.ts │ │ ├── instant.schema.ts │ │ ├── instant.schema.v2.ts │ │ ├── package.json │ │ ├── public │ │ │ └── vite.svg │ │ ├── src │ │ │ ├── App.tsx │ │ │ ├── index.css │ │ │ ├── main.tsx │ │ │ ├── typescript_branded.tsx │ │ │ ├── typescript_test_abstract.tsx │ │ │ ├── typescript_tests_backwards_compat_date.tsx │ │ │ ├── typescript_tests_experimental.tsx │ │ │ ├── typescript_tests_experimental_v2.tsx │ │ │ ├── typescript_tests_experimental_v2_no_schema.tsx │ │ │ ├── typescript_tests_normal.tsx │ │ │ ├── typescript_tests_normal_as_experimental.tsx │ │ │ └── vite-env.d.ts │ │ ├── tsconfig.app.json │ │ ├── tsconfig.json │ │ ├── tsconfig.node.json │ │ └── vite.config.ts │ ├── vanilla-js-nuxt │ │ ├── .gitignore │ │ ├── README.md │ │ ├── app.vue │ │ ├── nuxt.config.ts │ │ ├── package.json │ │ ├── public │ │ │ ├── favicon.ico │ │ │ └── robots.txt │ │ ├── server │ │ │ ├── api │ │ │ │ └── createId.ts │ │ │ └── tsconfig.json │ │ └── tsconfig.json │ └── vanilla-js-vite │ │ ├── .env.example │ │ ├── .gitignore │ │ ├── README.md │ │ ├── index.html │ │ ├── package.json │ │ ├── public │ │ └── vite.svg │ │ ├── schema.html │ │ ├── src │ │ ├── main.ts │ │ ├── schema.ts │ │ ├── style.css │ │ └── vite-env.d.ts │ │ ├── tsconfig.json │ │ └── vie.config.ts ├── scripts │ ├── fixImports.mjs │ └── publish_packages.clj ├── tsconfig.base.json ├── turbo.json ├── version.md └── www │ ├── .env │ ├── _emails │ ├── html │ │ ├── apr2025.html │ │ ├── dec2024.html │ │ ├── feb2025.html │ │ ├── mar2025.html │ │ ├── nov2024.html │ │ ├── oct2024.html │ │ └── welcome_feb_2025.html │ ├── markdown │ │ ├── apr2025.md │ │ ├── dec2024.md │ │ ├── feb2025.md │ │ ├── mar2025.md │ │ ├── nov2024.md │ │ ├── oct2024.md │ │ └── welcome_feb_2025.md │ ├── replace-images │ │ ├── index.mjs │ │ └── package.json │ └── txt │ │ ├── apr2025.txt │ │ ├── dec2024.txt │ │ ├── feb2025.txt │ │ ├── mar2025.txt │ │ ├── nov2024.txt │ │ ├── oct2024.txt │ │ └── welcome_feb_2025.txt │ ├── _posts │ ├── conj.md │ ├── datalogjs.md │ ├── db_browser.md │ ├── next_firebase.md │ ├── pg_upgrade.md │ ├── seed.md │ └── sync_future.md │ ├── components │ ├── AnimatedCounter.tsx │ ├── Dev.tsx │ ├── DocsPage.jsx │ ├── ErrorBoundary.tsx │ ├── admin │ │ └── AdminRoot.jsx │ ├── clientOnlyPage.tsx │ ├── dash │ │ ├── AppAuth.tsx │ │ ├── Auth.tsx │ │ ├── Billing.tsx │ │ ├── OAuthApps.tsx │ │ ├── Onboarding.tsx │ │ ├── Perms.tsx │ │ ├── PersonalAccessTokensScreen.tsx │ │ ├── Sandbox.tsx │ │ ├── auth │ │ │ ├── Apple.tsx │ │ │ ├── Clerk.tsx │ │ │ ├── Email.tsx │ │ │ ├── Google.tsx │ │ │ ├── Origins.tsx │ │ │ └── shared.tsx │ │ ├── explorer │ │ │ ├── EditNamespaceDialog.tsx │ │ │ ├── EditRowDialog.tsx │ │ │ ├── Explorer.tsx │ │ │ └── QueryInspector.tsx │ │ └── shared.tsx │ ├── docs │ │ ├── Ansi.jsx │ │ ├── Button.jsx │ │ ├── Callout.jsx │ │ ├── Fence.jsx │ │ ├── Icon.jsx │ │ ├── Layout.jsx │ │ ├── Logo.jsx │ │ ├── MobileNavigation.jsx │ │ ├── NavButton.jsx │ │ ├── Navigation.jsx │ │ ├── Prose.jsx │ │ ├── Search.jsx │ │ ├── ThemeSelector.jsx │ │ └── icons │ │ │ ├── InstallationIcon.jsx │ │ │ ├── LightbulbIcon.jsx │ │ │ ├── PluginsIcon.jsx │ │ │ ├── PresetsIcon.jsx │ │ │ ├── ThemingIcon.jsx │ │ │ └── WarningIcon.jsx │ ├── icons │ │ ├── NetlifyIcon.tsx │ │ └── VercelIcon.tsx │ ├── marketingUi.tsx │ └── ui.tsx │ ├── data │ ├── docsNavigation.js │ ├── tutorial-examples.ts │ ├── tutorial-snippets │ │ ├── todos-add-react.tsx │ │ ├── todos-update-delete-instant.tsx │ │ └── todos-update-delete-react.tsx │ └── tutorialMonacoTheme.json │ ├── examples.ts │ ├── lib │ ├── SelectedAppContext.ts │ ├── app.tsx │ ├── auth.ts │ ├── config.ts │ ├── contexts.ts │ ├── emails.js │ ├── errors.ts │ ├── feedback │ │ ├── RatingBox.tsx │ │ ├── clientDB.ts │ │ ├── instant.perms.ts │ │ └── instant.schema.ts │ ├── fetch.ts │ ├── flags.ts │ ├── footnotes.js │ ├── format.ts │ ├── hooks │ │ ├── explorer.tsx │ │ ├── useClickOutside.tsx │ │ ├── useCurrentDate.tsx │ │ ├── useDashFetch.tsx │ │ ├── useFlag.tsx │ │ ├── useForm.tsx │ │ ├── useIsHydrated.tsx │ │ ├── useIsOverflow.tsx │ │ ├── useLocalStorage.tsx │ │ └── useTotalSessionsCount.tsx │ ├── indexingJobs.ts │ ├── makeAttrComparator.tsx │ ├── markdoc.ts │ ├── muxVideos.ts │ ├── og.ts │ ├── posts.js │ ├── relationships.ts │ ├── schema.tsx │ ├── toast.js │ ├── types.ts │ ├── url.tsx │ └── videos.js │ ├── markdoc │ ├── nodes.js │ └── tags.js │ ├── next-env.d.ts │ ├── next-sitemap.config.js │ ├── next.config.js │ ├── package.json │ ├── pages │ ├── 404.tsx │ ├── _app.tsx │ ├── _devtool │ │ └── index.tsx │ ├── _document.js │ ├── api │ │ └── og.tsx │ ├── dash │ │ ├── index.tsx │ │ └── oauth │ │ │ └── callback.tsx │ ├── debug-uri │ │ └── [trace-id] │ │ │ └── [span-id].tsx │ ├── docs │ │ ├── auth.md │ │ ├── auth │ │ │ ├── apple.md │ │ │ ├── clerk.md │ │ │ ├── google-oauth.md │ │ │ ├── magic-codes.md │ │ │ └── platform-oauth.md │ │ ├── backend.md │ │ ├── cli.md │ │ ├── common-mistakes.md │ │ ├── devtool.md │ │ ├── emails.md │ │ ├── index.md │ │ ├── init.md │ │ ├── instaml.md │ │ ├── instaql.md │ │ ├── modeling-data.md │ │ ├── patterns.md │ │ ├── permissions.md │ │ ├── presence-and-topics.md │ │ ├── showcase.md │ │ ├── start-rn.md │ │ ├── start-vanilla.md │ │ ├── storage.md │ │ ├── teams.md │ │ ├── users.md │ │ └── using-llms.md │ ├── essays │ │ ├── [slug].tsx │ │ └── index.tsx │ ├── examples.tsx │ ├── examples │ │ ├── 1-todos.tsx │ │ ├── 2-auth.tsx │ │ ├── 3-cursors.tsx │ │ ├── 4-custom-cursors.tsx │ │ ├── 5-reactions.tsx │ │ ├── 6-typing-indicator.tsx │ │ ├── 7-avatar-stack.tsx │ │ └── 8-merge-tile-game.tsx │ ├── hiring │ │ ├── backend-engineer.tsx │ │ ├── full-stack-engineer.tsx │ │ ├── index.tsx │ │ └── typescript-engineer.tsx │ ├── index.tsx │ ├── intern │ │ ├── emails │ │ │ ├── [slug].tsx │ │ │ └── index.tsx │ │ ├── investor_updates.tsx │ │ ├── overview.tsx │ │ ├── paid.tsx │ │ ├── signup.tsx │ │ ├── storage.tsx │ │ └── top.jsx │ ├── labs │ │ ├── oauth_apps_demo.tsx │ │ └── platform_demo.tsx │ ├── platform │ │ └── oauth │ │ │ └── start.tsx │ ├── pricing │ │ └── index.tsx │ ├── privacy.tsx │ ├── resources │ │ └── ui.tsx │ ├── terms.tsx │ ├── tutorial-examples │ │ ├── 1-todos-add.tsx │ │ ├── 2-todos-edit.tsx │ │ └── 3-todos-attributes.tsx │ └── tutorial.tsx │ ├── postcss.config.js │ ├── public │ ├── fonts │ │ ├── BerkeleyMono-Bold.woff │ │ ├── BerkeleyMono-Bold.woff2 │ │ ├── BerkeleyMono-BoldItalic.woff │ │ ├── BerkeleyMono-BoldItalic.woff2 │ │ ├── BerkeleyMono-Italic.woff │ │ ├── BerkeleyMono-Italic.woff2 │ │ ├── BerkeleyMono-Regular.woff │ │ ├── BerkeleyMono-Regular.woff2 │ │ ├── BerkeleyMonoVariable-Italic.woff2 │ │ └── BerkeleyMonoVariable-Regular.woff2 │ ├── img │ │ ├── apple_logo_black.svg │ │ ├── clerk_logo_black.svg │ │ ├── docs │ │ │ ├── clerk-token-form.png │ │ │ ├── devtool-explorer.png │ │ │ ├── devtool-pointer.jpg │ │ │ ├── devtool-sandbox.png │ │ │ ├── instaml-due-date.png │ │ │ ├── instaql-data-intellisense.png │ │ │ ├── instaql-todos-goals-autocomplete.png │ │ │ ├── modeling-data-rename-attr.png │ │ │ ├── presence-intellisence.png │ │ │ └── rn-web-redirect-origins.png │ │ ├── emails │ │ │ ├── apr2025 │ │ │ │ ├── s_A8BCE826E2D24A59DDDF978FF919F212AA1BA53C7F2773B4B244E2F70CDD846A_1746560157623_image.png │ │ │ │ ├── s_A8BCE826E2D24A59DDDF978FF919F212AA1BA53C7F2773B4B244E2F70CDD846A_1746560354137_image.png │ │ │ │ ├── s_A8BCE826E2D24A59DDDF978FF919F212AA1BA53C7F2773B4B244E2F70CDD846A_1746564212953_better-oauth.png │ │ │ │ ├── s_D5033FA557FFFE14A26ED3674BAE74F345ABE2D9051159D5B3634332C24375B3_1746466781941_CleanShot+2025-05-05+at+10.39.092x.png │ │ │ │ └── s_DF8F10A9009F2A236BC7D07C4EC05DDA50E4FB82F40AA98593D3B98A1A7EA3DC_1730238267270_instant_header.png │ │ │ ├── dec2024 │ │ │ │ ├── s_A91D86B3D6F04CFEA63084B83C6E816ADC42104A6822CC9C6258E9D560CDF5F3_1735626509971_image.png │ │ │ │ ├── s_A91D86B3D6F04CFEA63084B83C6E816ADC42104A6822CC9C6258E9D560CDF5F3_1735626771452_image.png │ │ │ │ ├── s_A91D86B3D6F04CFEA63084B83C6E816ADC42104A6822CC9C6258E9D560CDF5F3_1735627523303_image.png │ │ │ │ └── s_DF8F10A9009F2A236BC7D07C4EC05DDA50E4FB82F40AA98593D3B98A1A7EA3DC_1730238267270_instant_header.png │ │ │ ├── feb2025 │ │ │ │ ├── s_513F5FE60B9BB3BB9CCD1CA54DF394804C0DE8F72ED1A4C65882EB8C31D175AE_1740786465619_add-links.png │ │ │ │ ├── s_513F5FE60B9BB3BB9CCD1CA54DF394804C0DE8F72ED1A4C65882EB8C31D175AE_1740787113300_image.png │ │ │ │ ├── s_513F5FE60B9BB3BB9CCD1CA54DF394804C0DE8F72ED1A4C65882EB8C31D175AE_1741040505548_image.png │ │ │ │ ├── s_513F5FE60B9BB3BB9CCD1CA54DF394804C0DE8F72ED1A4C65882EB8C31D175AE_1741044653859_cascade.png │ │ │ │ └── s_DF8F10A9009F2A236BC7D07C4EC05DDA50E4FB82F40AA98593D3B98A1A7EA3DC_1730238267270_instant_header.png │ │ │ ├── mar2025 │ │ │ │ ├── s_7B280E1A3BA8AB078D69579372DCD7F97D2F02F6D857FBABC05C42A70756AC62_1743727283805_image.png │ │ │ │ ├── s_7B280E1A3BA8AB078D69579372DCD7F97D2F02F6D857FBABC05C42A70756AC62_1743728983960_CleanShot+2025-04-03+at+18.09.332x.png │ │ │ │ ├── s_7B280E1A3BA8AB078D69579372DCD7F97D2F02F6D857FBABC05C42A70756AC62_1743788878099_image.png │ │ │ │ ├── s_7B280E1A3BA8AB078D69579372DCD7F97D2F02F6D857FBABC05C42A70756AC62_1744060894895_instant_hero.jpeg │ │ │ │ └── s_DF8F10A9009F2A236BC7D07C4EC05DDA50E4FB82F40AA98593D3B98A1A7EA3DC_1730238267270_instant_header.png │ │ │ ├── nov2024 │ │ │ │ ├── s_B097BA2FA68FBDBEF71F30F95558A3D23729AED0A557430F53FE49A682293BBC_1733449686289_image.png │ │ │ │ ├── s_B097BA2FA68FBDBEF71F30F95558A3D23729AED0A557430F53FE49A682293BBC_1733450241867_image.png │ │ │ │ ├── s_B097BA2FA68FBDBEF71F30F95558A3D23729AED0A557430F53FE49A682293BBC_1733450981289_image.png │ │ │ │ ├── s_B097BA2FA68FBDBEF71F30F95558A3D23729AED0A557430F53FE49A682293BBC_1733451107349_image.png │ │ │ │ ├── s_B097BA2FA68FBDBEF71F30F95558A3D23729AED0A557430F53FE49A682293BBC_1733451831476_image.png │ │ │ │ └── s_DF8F10A9009F2A236BC7D07C4EC05DDA50E4FB82F40AA98593D3B98A1A7EA3DC_1730238267270_instant_header.png │ │ │ └── oct2024 │ │ │ │ ├── s_B8A06116D3803694CDA0C13F9F97E92EA0220D4E377317F0F00D7831E3E41E9E_1727988124731_image.png │ │ │ │ ├── s_DF8F10A9009F2A236BC7D07C4EC05DDA50E4FB82F40AA98593D3B98A1A7EA3DC_1729122912083_image.png │ │ │ │ ├── s_DF8F10A9009F2A236BC7D07C4EC05DDA50E4FB82F40AA98593D3B98A1A7EA3DC_1729123513053_image.png │ │ │ │ ├── s_DF8F10A9009F2A236BC7D07C4EC05DDA50E4FB82F40AA98593D3B98A1A7EA3DC_1730238267270_instant_header.png │ │ │ │ ├── s_DF8F10A9009F2A236BC7D07C4EC05DDA50E4FB82F40AA98593D3B98A1A7EA3DC_1730244001267_image.png │ │ │ │ └── s_DF8F10A9009F2A236BC7D07C4EC05DDA50E4FB82F40AA98593D3B98A1A7EA3DC_1730244149277_users_table.png │ │ ├── google_g.svg │ │ ├── hiring │ │ │ ├── backend.png │ │ │ ├── explorer.png │ │ │ ├── sandbox.png │ │ │ └── sync_engine.png │ │ ├── icon │ │ │ ├── android-chrome-192x192.png │ │ │ ├── android-chrome-512x512.png │ │ │ ├── apple-touch-icon-114x114.png │ │ │ ├── apple-touch-icon-120x120.png │ │ │ ├── apple-touch-icon-144x144.png │ │ │ ├── apple-touch-icon-152x152.png │ │ │ ├── apple-touch-icon-167x167.png │ │ │ ├── apple-touch-icon-180x180.png │ │ │ ├── apple-touch-icon-57x57.png │ │ │ ├── apple-touch-icon-60x60.png │ │ │ ├── apple-touch-icon-72x72.png │ │ │ ├── apple-touch-icon-76x76.png │ │ │ ├── favicon-128x128.png │ │ │ ├── favicon-16x16.png │ │ │ ├── favicon-196x196.png │ │ │ ├── favicon-32x32.png │ │ │ ├── favicon-96x96.svg │ │ │ ├── logo-512.svg │ │ │ ├── logo_with_text.svg │ │ │ ├── mstile-144x144.png │ │ │ ├── mstile-150x150.png │ │ │ ├── mstile-310x150.png │ │ │ ├── mstile-310x310.png │ │ │ └── mstile-70x70.png │ │ ├── og_preview.png │ │ ├── peeps │ │ │ ├── aj_nandi.jpeg │ │ │ ├── alex.png │ │ │ ├── hunter.jpeg │ │ │ ├── james.png │ │ │ ├── nacho.jpg │ │ │ └── sean.png │ │ └── yc_logo.png │ ├── marketing │ │ ├── discord-icon.svg │ │ └── github-icon.svg │ ├── posts │ │ └── pg_upgrade │ │ │ ├── blue_green.png │ │ │ ├── clone_upgrade_replicate.png │ │ │ ├── create_replicate.png │ │ │ ├── going_manual.png │ │ │ ├── in_place.png │ │ │ ├── no_downtime.png │ │ │ ├── switch_subs.png │ │ │ ├── switch_writes.png │ │ │ └── the_system.png │ └── readmes │ │ ├── architecture.svg │ │ ├── compression.svg │ │ ├── logo_with_text_bg_white.svg │ │ ├── logo_with_text_dark_mode.svg │ │ └── logo_with_text_light_mode.svg │ ├── scripts │ ├── gen-llms-txt.ts │ ├── gen-md-docs.ts │ └── index-docs.ts │ ├── styles │ ├── docs │ │ ├── prism.css │ │ └── tailwind.css │ └── globals.css │ ├── tailwind.config.js │ └── tsconfig.json ├── server ├── .clj-kondo │ ├── .gitignore │ ├── ci-config.edn │ ├── config.edn │ ├── hooks │ │ ├── defsql.clj │ │ ├── with_indexing_job_queue.clj │ │ └── with_prod_conn.clj │ └── imports │ │ ├── babashka │ │ └── sci │ │ │ ├── config.edn │ │ │ └── sci │ │ │ └── core.clj │ │ ├── com.github.seancorfield │ │ └── next.jdbc │ │ │ ├── config.edn │ │ │ └── hooks │ │ │ └── com │ │ │ └── github │ │ │ └── seancorfield │ │ │ └── next_jdbc.clj_kondo │ │ ├── com.github.steffan-westcott │ │ └── clj-otel-api │ │ │ └── config.edn │ │ ├── hiccup │ │ └── hiccup │ │ │ ├── config.edn │ │ │ └── hiccup │ │ │ └── hooks.clj │ │ ├── http-kit │ │ └── http-kit │ │ │ ├── config.edn │ │ │ └── httpkit │ │ │ └── with_channel.clj │ │ ├── instaparse │ │ └── config.edn │ │ ├── io.github.tonsky │ │ └── clojure-plus │ │ │ ├── config.edn │ │ │ └── hooks │ │ │ └── core.clj │ │ ├── rewrite-clj │ │ └── rewrite-clj │ │ │ └── config.edn │ │ └── taoensso │ │ └── encore │ │ ├── config.edn │ │ └── taoensso │ │ └── encore.clj ├── .ebextensions │ ├── resources.config │ └── sysctl.config ├── .elasticbeanstalk │ └── config.yml ├── .gitignore ├── .platform │ └── hooks │ │ └── prebuild │ │ └── prebuild.sh ├── Dockerfile ├── Dockerfile-dev ├── Makefile ├── README.md ├── build.clj ├── ci_trigger.txt ├── deps.edn ├── dev-postgres │ ├── Dockerfile │ ├── Makefile │ └── README.md ├── dev-resources │ ├── circleci_test │ │ └── config.clj │ └── hooks │ │ └── pre-commit ├── dev │ ├── data_readers.clj │ └── user.clj ├── docker-compose-dev.yml ├── docker-compose.yml ├── flags-config │ ├── .env │ ├── README.md │ ├── instant.perms.ts │ ├── instant.schema.ts │ ├── package.json │ └── pnpm-lock.yaml ├── refinery │ ├── .ebextensions │ │ └── resources.config │ ├── config-redis.yaml │ ├── config.yaml │ ├── docker-compose.yml │ ├── refinery.env │ └── rules.yaml ├── resources │ ├── config │ │ ├── dev.edn │ │ ├── prod.edn │ │ ├── staging.edn │ │ └── test.edn │ ├── logback.xml │ ├── migrations │ │ ├── 01_bootstrap.down.sql │ │ ├── 01_bootstrap.up.sql │ │ ├── 02_add_grabs.down.sql │ │ ├── 02_add_grabs.up.sql │ │ ├── 03_add_transactions.down.sql │ │ ├── 03_add_transactions.up.sql │ │ ├── 04_add_rules.down.sql │ │ ├── 04_add_rules.up.sql │ │ ├── 05_add_app_admin_tokens.down.sql │ │ ├── 05_add_app_admin_tokens.up.sql │ │ ├── 06_fix_ref_constraint_on_triples.down.sql │ │ ├── 06_fix_ref_constraint_on_triples.up.sql │ │ ├── 07_add_profiles.down.sql │ │ ├── 07_add_profiles.up.sql │ │ ├── 08_add_createdAt_for_triples.down.sql │ │ ├── 08_add_createdAt_for_triples.up.sql │ │ ├── 09_add_oauth_login.down.sql │ │ ├── 09_add_oauth_login.up.sql │ │ ├── 10_add_app_oauth_login.down.sql │ │ ├── 10_add_app_oauth_login.up.sql │ │ ├── 11_add_created_at_fields.down.sql │ │ ├── 11_add_created_at_fields.up.sql │ │ ├── 12_add_redirect_to_dev.down.sql │ │ ├── 12_add_redirect_to_dev.up.sql │ │ ├── 13_add_discovery_endpoint.down.sql │ │ ├── 13_add_discovery_endpoint.up.sql │ │ ├── 14_add_apps_created_at_index.down.sql │ │ ├── 14_add_apps_created_at_index.up.sql │ │ ├── 15_pkce.down.sql │ │ ├── 15_pkce.up.sql │ │ ├── 16_add_stripe.down.sql │ │ ├── 16_add_stripe.up.sql │ │ ├── 17_add_teams.down.sql │ │ ├── 17_add_teams.up.sql │ │ ├── 18_add_sent_at_to_invites.down.sql │ │ ├── 18_add_sent_at_to_invites.up.sql │ │ ├── 19_add_app_email_templates.down.sql │ │ ├── 19_add_app_email_templates.up.sql │ │ ├── 20_add_name_to_app_email_templates.down.sql │ │ ├── 20_add_name_to_app_email_templates.up.sql │ │ ├── 21_change_sender_ownership_model.down.sql │ │ ├── 21_change_sender_ownership_model.up.sql │ │ ├── 22_drop_app_id_from_senders.down.sql │ │ ├── 22_drop_app_id_from_senders.up.sql │ │ ├── 23_jsonb_dmerge_and_raise.down.sql │ │ ├── 23_jsonb_dmerge_and_raise.up.sql │ │ ├── 24_deep_merge_null.down.sql │ │ ├── 24_deep_merge_null.up.sql │ │ ├── 25_byop_connection_string.down.sql │ │ ├── 25_byop_connection_string.up.sql │ │ ├── 26_cli_auth.down.sql │ │ ├── 26_cli_auth.up.sql │ │ ├── 27_inferred_type.down.sql │ │ ├── 27_inferred_type.up.sql │ │ ├── 28_config.down.sql │ │ ├── 28_config.up.sql │ │ ├── 29_clerk.down.sql │ │ ├── 29_clerk.up.sql │ │ ├── 30_personal_access_tokens.down.sql │ │ ├── 30_personal_access_tokens.up.sql │ │ ├── 31_attrs_replica_full.down.sql │ │ ├── 31_attrs_replica_full.up.sql │ │ ├── 32_pgcrypto.down.sql │ │ ├── 32_pgcrypto.up.sql │ │ ├── 33_users_in_triples_flag.down.sql │ │ ├── 33_users_in_triples_flag.up.sql │ │ ├── 34_hardcoded_objects.down.sql │ │ ├── 34_hardcoded_objects.up.sql │ │ ├── 35_cascade_delete.down.sql │ │ ├── 35_cascade_delete.up.sql │ │ ├── 36_checked_data_type.down.sql │ │ ├── 36_checked_data_type.up.sql │ │ ├── 37_remove_users_in_triples_flag.down.sql │ │ ├── 37_remove_users_in_triples_flag.up.sql │ │ ├── 38_uniqueing.down.sql │ │ ├── 38_uniqueing.up.sql │ │ ├── 39_fix_extract_boolean.down.sql │ │ ├── 39_fix_extract_boolean.up.sql │ │ ├── 40_checked_indexes.down.sql │ │ ├── 40_checked_indexes.up.sql │ │ ├── 41_primary_keys.down.sql │ │ ├── 41_primary_keys.up.sql │ │ ├── 42_add_transactions_app_id_idx.down.sql │ │ ├── 42_add_transactions_app_id_idx.up.sql │ │ ├── 43_specify_public.down.sql │ │ ├── 43_specify_public.up.sql │ │ ├── 44_add_daily_app_transactions.down.sql │ │ ├── 44_add_daily_app_transactions.up.sql │ │ ├── 45_remove_entity_id_from_indexes.down.sql │ │ ├── 45_remove_entity_id_from_indexes.up.sql │ │ ├── 46_add_created_at_index_to_transactions.down.sql │ │ ├── 46_add_created_at_index_to_transactions.up.sql │ │ ├── 47_add_replica_id_to_daily_metrics.down.sql │ │ ├── 47_add_replica_id_to_daily_metrics.up.sql │ │ ├── 48_add_dap_primary_key.down.sql │ │ ├── 48_add_dap_primary_key.up.sql │ │ ├── 49_add_user_flags.down.sql │ │ ├── 49_add_user_flags.up.sql │ │ ├── 50_add_app_upload_urls.down.sql │ │ ├── 50_add_app_upload_urls.up.sql │ │ ├── 51_add_triples_created_at_index.down.sql │ │ ├── 51_add_triples_created_at_index.up.sql │ │ ├── 52_add_app_files_to_sweep.down.sql │ │ ├── 52_add_app_files_to_sweep.up.sql │ │ ├── 53_change_indexing_of_triple_nulls.down.sql │ │ ├── 53_change_indexing_of_triple_nulls.up.sql │ │ ├── 54_on_delete_reverse.down.sql │ │ ├── 54_on_delete_reverse.up.sql │ │ ├── 55_add_storage_sweeper.down.sql │ │ ├── 55_add_storage_sweeper.up.sql │ │ ├── 56_nulls_first_indexes.down.sql │ │ ├── 56_nulls_first_indexes.up.sql │ │ ├── 57_apps_deletion.down.sql │ │ ├── 57_apps_deletion.up.sql │ │ ├── 58_instant_oauth_provider.down.sql │ │ ├── 58_instant_oauth_provider.up.sql │ │ ├── 59_is_required.down.sql │ │ ├── 59_is_required.up.sql │ │ ├── 60_statistics.down.sql │ │ ├── 60_statistics.up.sql │ │ ├── 61_seed_test_user.down.sql │ │ ├── 61_seed_test_user.up.sql │ │ ├── 62_seed_ephemeral_app_creator.down.sql │ │ ├── 62_seed_ephemeral_app_creator.up.sql │ │ ├── 63_seed_homepage_app.down.sql │ │ ├── 63_seed_homepage_app.up.sql │ │ ├── 64_better_uuid_constraint.down.sql │ │ ├── 64_better_uuid_constraint.up.sql │ │ ├── 65_drop_old_constraint.down.sql │ │ ├── 65_drop_old_constraint.up.sql │ │ ├── 66_indexing_jobs_error_data.down.sql │ │ ├── 66_indexing_jobs_error_data.up.sql │ │ ├── 67_personal_access_token_lookup.down.sql │ │ ├── 67_personal_access_token_lookup.up.sql │ │ ├── 68_attrs_etype_label_schema.down.sql │ │ ├── 68_attrs_etype_label_schema.up.sql │ │ ├── 69_attrs_etype_label_data.down.sql │ │ ├── 69_attrs_etype_label_data.up.sql │ │ ├── 70_improve_file_system_attrs.down.sql │ │ └── 70_improve_file_system_attrs.up.sql │ ├── sample_triples │ │ ├── movie.json │ │ └── zeneca.json │ └── uri-schemes.edn ├── scripts │ ├── aws_tunnel.sh │ ├── clone_app.sh │ ├── clone_app.sql │ ├── eb_deploy.clj │ ├── export.sh │ ├── export │ │ ├── copy_apps.sql │ │ ├── copy_attrs.sql │ │ ├── copy_idents.sql │ │ ├── copy_rules.sql │ │ └── copy_triples.sql │ ├── install_dev_certs.sh │ ├── manual_deploy.sh │ ├── prod_connection_string.sh │ ├── prod_ssh.sh │ ├── prod_tunnel.sh │ └── yourkit_tunnel.sh ├── src │ ├── instant │ │ ├── admin │ │ │ ├── model.clj │ │ │ └── routes.clj │ │ ├── app_deletion_sweeper.clj │ │ ├── aurora_config.clj │ │ ├── auth │ │ │ ├── jwt.clj │ │ │ └── oauth.clj │ │ ├── comment.clj │ │ ├── config.clj │ │ ├── config_edn.clj │ │ ├── core.clj │ │ ├── dash │ │ │ ├── admin.clj │ │ │ ├── ephemeral_app.clj │ │ │ └── routes.clj │ │ ├── data │ │ │ ├── bootstrap.clj │ │ │ ├── constants.clj │ │ │ └── resolvers.clj │ │ ├── db │ │ │ ├── cel.clj │ │ │ ├── dataloader.clj │ │ │ ├── datalog.clj │ │ │ ├── indexing_jobs.clj │ │ │ ├── instaql.clj │ │ │ ├── model │ │ │ │ ├── attr.clj │ │ │ │ ├── attr_pat.clj │ │ │ │ ├── entity.clj │ │ │ │ ├── transaction.clj │ │ │ │ ├── triple.clj │ │ │ │ └── triple_cols.clj │ │ │ ├── permissioned_transaction.clj │ │ │ ├── pg_introspect.clj │ │ │ ├── rule_where_testing.clj │ │ │ └── transaction.clj │ │ ├── discord.clj │ │ ├── fixtures.clj │ │ ├── flags.clj │ │ ├── flags_impl.clj │ │ ├── gauges.clj │ │ ├── grab.clj │ │ ├── grouped_queue.clj │ │ ├── health.clj │ │ ├── honeycomb_api.clj │ │ ├── intern │ │ │ └── metrics.clj │ │ ├── jdbc │ │ │ ├── aurora.clj │ │ │ ├── failover.clj │ │ │ ├── pgerrors.clj │ │ │ ├── sql.clj │ │ │ └── wal.clj │ │ ├── lib │ │ │ └── ring │ │ │ │ ├── undertow.clj │ │ │ │ └── websocket.clj │ │ ├── machine_summaries.clj │ │ ├── model │ │ │ ├── app.clj │ │ │ ├── app_admin_token.clj │ │ │ ├── app_authorized_redirect_origin.clj │ │ │ ├── app_email_sender.clj │ │ │ ├── app_email_template.clj │ │ │ ├── app_file.clj │ │ │ ├── app_member_invites.clj │ │ │ ├── app_members.clj │ │ │ ├── app_oauth_client.clj │ │ │ ├── app_oauth_code.clj │ │ │ ├── app_oauth_redirect.clj │ │ │ ├── app_oauth_service_provider.clj │ │ │ ├── app_upload_url.clj │ │ │ ├── app_user.clj │ │ │ ├── app_user_magic_code.clj │ │ │ ├── app_user_oauth_link.clj │ │ │ ├── app_user_refresh_token.clj │ │ │ ├── instant_cli_login.clj │ │ │ ├── instant_oauth_code.clj │ │ │ ├── instant_oauth_redirect.clj │ │ │ ├── instant_personal_access_token.clj │ │ │ ├── instant_profile.clj │ │ │ ├── instant_stripe_customer.clj │ │ │ ├── instant_subscription.clj │ │ │ ├── instant_user.clj │ │ │ ├── instant_user_magic_code.clj │ │ │ ├── instant_user_refresh_token.clj │ │ │ ├── oauth_app.clj │ │ │ ├── outreach.clj │ │ │ ├── rule.clj │ │ │ └── schema.clj │ │ ├── nrepl.clj │ │ ├── oauth_apps │ │ │ └── routes.clj │ │ ├── postmark.clj │ │ ├── reactive │ │ │ ├── ephemeral.clj │ │ │ ├── invalidator.clj │ │ │ ├── query.clj │ │ │ ├── receive_queue.clj │ │ │ ├── session.clj │ │ │ └── store.clj │ │ ├── runtime │ │ │ └── routes.clj │ │ ├── scratch │ │ │ ├── backtest.clj │ │ │ ├── backtest_vars.clj │ │ │ └── export.clj │ │ ├── scripts │ │ │ ├── analytics.clj │ │ │ ├── daily_metrics.clj │ │ │ ├── newsletter.clj │ │ │ └── welcome_email.clj │ │ ├── sendgrid.clj │ │ ├── session_counter.clj │ │ ├── storage │ │ │ ├── beta.clj │ │ │ ├── coordinator.clj │ │ │ ├── routes.clj │ │ │ ├── s3.clj │ │ │ └── sweeper.clj │ │ ├── stripe.clj │ │ ├── superadmin │ │ │ └── routes.clj │ │ ├── system_catalog.clj │ │ ├── system_catalog_migration.clj │ │ ├── system_catalog_ops.clj │ │ └── util │ │ │ ├── async.clj │ │ │ ├── aws.clj │ │ │ ├── aws_signature.clj │ │ │ ├── cache.clj │ │ │ ├── coll.clj │ │ │ ├── crypt.clj │ │ │ ├── date.clj │ │ │ ├── delay.clj │ │ │ ├── e2e_tracer.clj │ │ │ ├── email.clj │ │ │ ├── exception.clj │ │ │ ├── hazelcast.clj │ │ │ ├── http.clj │ │ │ ├── instaql.clj │ │ │ ├── io.clj │ │ │ ├── json.clj │ │ │ ├── lang.clj │ │ │ ├── logging_exporter.clj │ │ │ ├── number.clj │ │ │ ├── pg_hint_plan.clj │ │ │ ├── s3.clj │ │ │ ├── semver.clj │ │ │ ├── spec.clj │ │ │ ├── string.clj │ │ │ ├── test.clj │ │ │ ├── token.clj │ │ │ ├── tracer.clj │ │ │ ├── url.clj │ │ │ └── uuid.clj │ ├── java │ │ └── instant │ │ │ └── SpanTrackException.java │ ├── tasks.clj │ └── tool.clj └── test │ └── instant │ ├── admin │ └── routes_test.clj │ ├── config_edn_test.clj │ ├── db │ ├── cel_test.clj │ ├── datalog_test.clj │ ├── indexing_jobs_test.clj │ ├── instaql_test.clj │ └── transaction_test.clj │ ├── grouped_queue_test.clj │ ├── jdbc │ └── sql_test.clj │ ├── model │ ├── app_authorized_redirect_origin_test.clj │ └── rule_test.clj │ ├── reactive │ ├── invalidator_test.clj │ ├── session_test.clj │ └── store_test.clj │ ├── storage │ ├── s3_test.clj │ └── sweeper_test.clj │ ├── stripe_test.clj │ ├── test_core.clj │ └── util │ ├── async_test.clj │ ├── aws_signature_test.clj │ ├── exception_test.clj │ ├── hazelcast_test.clj │ ├── semver_test.clj │ └── uuid_test.clj └── vercel.json /.git-blame-ignore-revs: -------------------------------------------------------------------------------- 1 | # Enforced prettier formatting: https://github.com/instantdb/instant/pull/810 2 | de921d5ae4821cada6af1f5d11068f8f5d63e27d 3 | -------------------------------------------------------------------------------- /.github/actions/elastic-beanstalk/.yarnrc.yml: -------------------------------------------------------------------------------- 1 | nodeLinker: node-modules 2 | -------------------------------------------------------------------------------- /.github/actions/elastic-beanstalk/README.md: -------------------------------------------------------------------------------- 1 | # elastic-beanstalk action 2 | 3 | Creates a new application version in elastic beanstalk. 4 | -------------------------------------------------------------------------------- /.github/actions/elastic-beanstalk/action.yml: -------------------------------------------------------------------------------- 1 | name: elasticbeanstalk 2 | description: Publish artifacts to elasticbeanstalk 3 | author: dwwoelfel 4 | 5 | # Define your inputs here. 6 | inputs: 7 | working-directory: 8 | description: The working directory 9 | required: true 10 | files: 11 | description: JSON-encoded list of files that should be included in the bundle 12 | required: true 13 | aws-region: 14 | required: true 15 | bucket: 16 | description: The bucket that the elastic beanstalk zip files get uploaded to 17 | required: true 18 | application-name: 19 | description: The name of the elasticbeanstalk application 20 | required: true 21 | 22 | 23 | # Define your outputs here. 24 | outputs: 25 | version: 26 | description: The application version that was created 27 | 28 | runs: 29 | using: node20 30 | main: bin/index.js 31 | -------------------------------------------------------------------------------- /.github/actions/elastic-beanstalk/src/index.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * The entrypoint for the action. 3 | */ 4 | import { run } from "./main"; 5 | 6 | run(); 7 | -------------------------------------------------------------------------------- /.github/actions/elastic-beanstalk/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es2015", 4 | "moduleResolution": "node", 5 | "allowSyntheticDefaultImports": true 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /client/.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [**/*.{js,jsx,ts,tsx,json,md}] 4 | charset = utf-8 5 | trim_trailing_whitespace = true 6 | insert_final_newline = true 7 | indent_style = space 8 | indent_size = 2 9 | -------------------------------------------------------------------------------- /client/.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "semi": true, 3 | "singleQuote": true 4 | } 5 | -------------------------------------------------------------------------------- /client/packages/admin/.npmignore: -------------------------------------------------------------------------------- 1 | .turbo 2 | -------------------------------------------------------------------------------- /client/packages/admin/src/version.js: -------------------------------------------------------------------------------- 1 | // Autogenerated by publish_packages.clj 2 | const version = 'v0.19.14-dev'; 3 | 4 | export default version; 5 | -------------------------------------------------------------------------------- /client/packages/admin/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.base.json", 3 | "include": ["src"], 4 | "exclude": ["node_modules", "dist"], 5 | "compilerOptions": { 6 | "outDir": "dist/tsc", 7 | "rewriteRelativeImportExtensions": true, 8 | "rootDir": "src" 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /client/packages/cli/bin/index.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | import '../dist/index.js'; 4 | -------------------------------------------------------------------------------- /client/packages/cli/src/util/fs.ts: -------------------------------------------------------------------------------- 1 | import { PathLike } from 'fs'; 2 | import { readFile, stat } from 'fs/promises'; 3 | 4 | export async function pathExists(p: PathLike): Promise { 5 | try { 6 | await stat(p); 7 | return true; 8 | } catch { 9 | return false; 10 | } 11 | } 12 | 13 | export async function readJsonFile>( 14 | p: PathLike, 15 | ): Promise { 16 | if (!pathExists(p)) { 17 | return null; 18 | } 19 | 20 | try { 21 | const data = await readFile(p, 'utf-8'); 22 | return JSON.parse(data); 23 | } catch (error) {} 24 | 25 | return null; 26 | } 27 | -------------------------------------------------------------------------------- /client/packages/cli/src/version.js: -------------------------------------------------------------------------------- 1 | // Autogenerated by publish_packages.clj 2 | const version = 'v0.19.14-dev'; 3 | 4 | export default version; 5 | -------------------------------------------------------------------------------- /client/packages/cli/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.base.json", 3 | "compilerOptions": { 4 | "outDir": "dist", 5 | "rootDir": "src", 6 | "skipLibCheck": true // `unconfig` currently imports a broken type from `@antfu/utils` 7 | // remove once fixed 8 | }, 9 | "include": ["src"], 10 | "exclude": ["node_modules", "dist"] 11 | } 12 | -------------------------------------------------------------------------------- /client/packages/core/.npmignore: -------------------------------------------------------------------------------- 1 | .turbo 2 | -------------------------------------------------------------------------------- /client/packages/core/__example__/standalone.esm.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Instant Core ESM standalone example/test 7 | 8 | 9 | 10 | 11 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /client/packages/core/__example__/standalone.umd.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Instant Core UMD standalone example/test 7 | 8 | 9 | 10 | 11 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /client/packages/core/__tests__/src/instaql.bench.js: -------------------------------------------------------------------------------- 1 | import { bench } from 'vitest'; 2 | 3 | import zenecaAttrs from './data/zeneca/attrs.json'; 4 | import zenecaTriples from './data/zeneca/triples.json'; 5 | import { createStore } from '../../src/store'; 6 | import query from '../../src/instaql'; 7 | 8 | const zenecaIdToAttr = zenecaAttrs.reduce((res, x) => { 9 | res[x.id] = x; 10 | return res; 11 | }, {}); 12 | 13 | const store = createStore(zenecaIdToAttr, zenecaTriples); 14 | 15 | bench('big query', () => { 16 | query( 17 | { store }, 18 | { 19 | users: { 20 | bookshelves: { 21 | books: {}, 22 | users: { 23 | bookshelves: {}, 24 | }, 25 | }, 26 | }, 27 | }, 28 | ); 29 | }); 30 | -------------------------------------------------------------------------------- /client/packages/core/src/InMemoryStorage.js: -------------------------------------------------------------------------------- 1 | export default class InMemoryStorage { 2 | constructor(dbName) { 3 | this.dbName = dbName; 4 | this.store = new Map(); 5 | } 6 | 7 | async getItem(k) { 8 | return this.store.get(k) ?? null; 9 | } 10 | 11 | async setItem(k, v) { 12 | this.store.set(k, v); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /client/packages/core/src/WindowNetworkListener.js: -------------------------------------------------------------------------------- 1 | export default class WindowNetworkListener { 2 | static async getIsOnline() { 3 | return navigator.onLine; 4 | } 5 | static listen(f) { 6 | const onOnline = () => { 7 | f(true); 8 | }; 9 | const onOffline = () => { 10 | f(false); 11 | }; 12 | addEventListener('online', onOnline); 13 | addEventListener('offline', onOffline); 14 | return () => { 15 | removeEventListener('online', onOnline); 16 | removeEventListener('offline', onOffline); 17 | }; 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /client/packages/core/src/clientTypes.ts: -------------------------------------------------------------------------------- 1 | export type User = { id: string; email: string; refresh_token: string }; 2 | 3 | export type AuthResult = 4 | | { user: User | undefined; error: undefined } 5 | | { user: undefined; error: { message: string } }; 6 | 7 | export type AuthState = 8 | | { isLoading: true; error: undefined; user: undefined } 9 | | { isLoading: false; error: { message: string }; user: undefined } 10 | | { isLoading: false; error: undefined; user: User | null }; 11 | 12 | export type ConnectionStatus = 13 | | 'connecting' 14 | | 'opened' 15 | | 'authenticated' 16 | | 'closed' 17 | | 'errored'; 18 | -------------------------------------------------------------------------------- /client/packages/core/src/model/instaqlResult.js: -------------------------------------------------------------------------------- 1 | function _extractTriplesHelper(idNodes, acc = []) { 2 | idNodes.forEach((idNode) => { 3 | const { data } = idNode; 4 | const { 'datalog-result': datalogResult } = data; 5 | const { 'join-rows': joinRows } = datalogResult; 6 | for (const rows of joinRows) { 7 | for (const triple of rows) { 8 | acc.push(triple); 9 | } 10 | } 11 | _extractTriplesHelper(idNode['child-nodes'], acc); 12 | }); 13 | } 14 | 15 | /** 16 | * Marshall instaql-result into list of triples. Instaql-result may have 17 | * multiple datalog-results, each datalog-result may have multiple join-rows 18 | * and each join-row may have triples.The union of these triples may have 19 | * duplicates, so we dedup them. 20 | */ 21 | export function extractTriples(idNodes) { 22 | const triples = []; 23 | _extractTriplesHelper(idNodes, triples); 24 | return triples; 25 | } 26 | -------------------------------------------------------------------------------- /client/packages/core/src/rulesTypes.ts: -------------------------------------------------------------------------------- 1 | import { InstantSchemaDef, InstantUnknownSchema } from './schemaTypes.ts'; 2 | 3 | export type InstantRulesAllowBlock = { 4 | $default?: string | null | undefined; 5 | view?: string | null | undefined; 6 | create?: string | null | undefined; 7 | update?: string | null | undefined; 8 | delete?: string | null | undefined; 9 | }; 10 | 11 | export type InstantRules< 12 | Schema extends InstantSchemaDef = InstantUnknownSchema, 13 | > = { 14 | $default?: { bind?: string[]; allow: InstantRulesAllowBlock }; 15 | attrs?: { bind?: string[]; allow: InstantRulesAllowBlock }; 16 | } & { 17 | [EntityName in keyof Schema['entities']]: { 18 | bind?: string[]; 19 | allow: InstantRulesAllowBlock; 20 | }; 21 | }; 22 | -------------------------------------------------------------------------------- /client/packages/core/src/utils/Deferred.js: -------------------------------------------------------------------------------- 1 | export class Deferred { 2 | promise; 3 | _resolve; 4 | _reject; 5 | 6 | constructor() { 7 | this.promise = new Promise((resolve, reject) => { 8 | this._resolve = resolve; 9 | this._reject = reject; 10 | }); 11 | } 12 | 13 | resolve(value) { 14 | this._resolve(value); 15 | } 16 | 17 | reject(reason) { 18 | this._reject(reason); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /client/packages/core/src/utils/error.ts: -------------------------------------------------------------------------------- 1 | export function assert(condition: any, msg?: string): asserts condition { 2 | if (!condition) { 3 | throw new Error('[assertion error] ' + msg); 4 | } 5 | } 6 | 7 | export function assertUnreachable(_x: never): never { 8 | throw new Error('[assertion error] TS should prevent us from reaching here'); 9 | } 10 | -------------------------------------------------------------------------------- /client/packages/core/src/utils/flags.ts: -------------------------------------------------------------------------------- 1 | let devBackend = false; 2 | let instantLogs = false; 3 | let devtoolLocalDashboard = false; 4 | 5 | if ( 6 | typeof window !== 'undefined' && 7 | typeof window.localStorage !== 'undefined' 8 | ) { 9 | devBackend = !!window.localStorage.getItem('devBackend'); 10 | instantLogs = !!window.localStorage.getItem('__instantLogging'); 11 | devtoolLocalDashboard = !!window.localStorage.getItem('__devtoolLocalDash'); 12 | } 13 | 14 | export { devBackend, instantLogs, devtoolLocalDashboard }; 15 | -------------------------------------------------------------------------------- /client/packages/core/src/utils/linkIndex.ts: -------------------------------------------------------------------------------- 1 | import type { InstantGraph, LinkDef, LinksDef } from '../schemaTypes.ts'; 2 | 3 | export type LinkIndex = Record< 4 | string, 5 | Record< 6 | string, 7 | { 8 | isForward: boolean; 9 | isSingular: boolean; 10 | link: LinkDef; 11 | } 12 | > 13 | >; 14 | 15 | export function createLinkIndex(schema: InstantGraph>) { 16 | return Object.values(schema.links).reduce((linkIndex, link) => { 17 | linkIndex[link.forward.on] ??= {}; 18 | linkIndex[link.forward.on][link.forward.label] = { 19 | isForward: true, 20 | isSingular: link.forward.has === 'one', 21 | link, 22 | }; 23 | 24 | linkIndex[link.reverse.on] ??= {}; 25 | linkIndex[link.reverse.on][link.reverse.label] = { 26 | isForward: false, 27 | isSingular: link.reverse.has === 'one', 28 | link, 29 | }; 30 | 31 | return linkIndex; 32 | }, {} as LinkIndex); 33 | } 34 | -------------------------------------------------------------------------------- /client/packages/core/src/utils/log.ts: -------------------------------------------------------------------------------- 1 | export interface Logger { 2 | info: (...args: any[]) => void; 3 | debug: (...args: any[]) => void; 4 | error: (...args: any[]) => void; 5 | } 6 | 7 | export default function createLogger(isEnabled: boolean): Logger { 8 | return { 9 | info: isEnabled ? console.info.bind(console) : () => {}, 10 | debug: isEnabled ? console.debug.bind(console) : () => {}, 11 | error: isEnabled ? console.error.bind(console) : () => {}, 12 | }; 13 | } 14 | -------------------------------------------------------------------------------- /client/packages/core/src/utils/pick.js: -------------------------------------------------------------------------------- 1 | export function pick(obj, keys) { 2 | if (!keys) return obj; 3 | 4 | const ret = {}; 5 | keys.forEach((key) => { 6 | ret[key] = obj[key]; 7 | }); 8 | return ret; 9 | } 10 | -------------------------------------------------------------------------------- /client/packages/core/src/utils/uuid.ts: -------------------------------------------------------------------------------- 1 | import { v4 } from 'uuid'; 2 | 3 | function uuidToByteArray(uuid: string) { 4 | const hex = uuid.replace(/-/g, ''); 5 | const bytes = []; 6 | for (let i = 0; i < hex.length; i += 2) { 7 | bytes.push(parseInt(hex.substring(i, i + 2), 16)); 8 | } 9 | return bytes; 10 | } 11 | 12 | function compareByteArrays(a, b) { 13 | for (let i = 0; i < a.length; i++) { 14 | if (a[i] < b[i]) return -1; 15 | if (a[i] > b[i]) return 1; 16 | } 17 | return 0; 18 | } 19 | 20 | export function uuidCompare(uuid_a: string, uuid_b: string) { 21 | return compareByteArrays(uuidToByteArray(uuid_a), uuidToByteArray(uuid_b)); 22 | } 23 | 24 | function id(): string { 25 | return v4(); 26 | } 27 | 28 | export default id; 29 | -------------------------------------------------------------------------------- /client/packages/core/src/version.js: -------------------------------------------------------------------------------- 1 | // Autogenerated by publish_packages.clj 2 | const version = 'v0.19.14-dev'; 3 | 4 | export default version; 5 | -------------------------------------------------------------------------------- /client/packages/core/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.base.json", 3 | "include": ["src"], 4 | "exclude": ["node_modules", "dist"], 5 | "compilerOptions": { 6 | "outDir": "dist/tsc", 7 | "rewriteRelativeImportExtensions": true, 8 | "rootDir": "src", 9 | "checkJs": false 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /client/packages/core/vite.config.ts: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'vite'; 2 | import { resolve } from 'path'; 3 | 4 | export default defineConfig({ 5 | clearScreen: false, 6 | build: { 7 | outDir: 'dist/standalone', 8 | lib: { 9 | formats: ['umd', 'es'], 10 | // this is the file that exports our components 11 | entry: resolve(__dirname, 'src', 'index.ts'), 12 | name: 'instant', 13 | fileName: 'index', 14 | }, 15 | }, 16 | define: { 17 | 'process.env': {}, 18 | }, 19 | }); 20 | -------------------------------------------------------------------------------- /client/packages/platform/__tests__/src/test.ts: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/instantdb/instant/fd03a3aa4a0074e6d4a61eb522d435f43eba9655/client/packages/platform/__tests__/src/test.ts -------------------------------------------------------------------------------- /client/packages/platform/src/crypto.ts: -------------------------------------------------------------------------------- 1 | // https://tools.ietf.org/html/rfc7636#section-4.1 2 | export function pkceVerifier(): string { 3 | const chars = 4 | '0123456789AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz-._~'; 5 | let s = ''; 6 | 7 | for (const value of crypto.getRandomValues(new Uint8Array(64))) { 8 | s = s + chars[value % chars.length]; 9 | } 10 | 11 | return s; 12 | } 13 | 14 | export function sha256(s: string): Promise { 15 | return crypto.subtle.digest({ name: 'SHA-256' }, new TextEncoder().encode(s)); 16 | } 17 | 18 | function urlSafeBase64(s: string): string { 19 | return s.replace(/\+/g, '-').replace(/\//g, '_').replace(/=/g, ''); 20 | } 21 | 22 | export function pkceCodeChallengeOfVerifier(verifier: string): Promise { 23 | return sha256(verifier).then((s) => { 24 | return urlSafeBase64( 25 | btoa(String.fromCharCode(...Array.from(new Uint8Array(s)))), 26 | ); 27 | }); 28 | } 29 | -------------------------------------------------------------------------------- /client/packages/platform/src/index.ts: -------------------------------------------------------------------------------- 1 | import { InstantOAuthError, type OAuthScope } from './oauthCommon.ts'; 2 | import { 3 | type InstantDBOAuthAccessToken, 4 | type OAuthHandlerConfig, 5 | OAuthHandler, 6 | } from './oauth.ts'; 7 | import { generatePermsTypescriptFile } from './perms.ts'; 8 | import { 9 | type InstantAPIPlatformSchema, 10 | generateSchemaTypescriptFile, 11 | } from './schema.ts'; 12 | import { PlatformApi, translatePlanSteps } from './api.ts'; 13 | 14 | import version from './version.js'; 15 | import { ProgressPromise } from './ProgressPromise.ts'; 16 | import { i, type InstantRules } from '@instantdb/core'; 17 | 18 | export { 19 | type InstantAPIPlatformSchema, 20 | type InstantDBOAuthAccessToken, 21 | type OAuthHandlerConfig, 22 | type OAuthScope, 23 | type InstantRules, 24 | OAuthHandler, 25 | InstantOAuthError, 26 | generateSchemaTypescriptFile, 27 | generatePermsTypescriptFile, 28 | version, 29 | translatePlanSteps, 30 | PlatformApi, 31 | ProgressPromise, 32 | i, 33 | }; 34 | -------------------------------------------------------------------------------- /client/packages/platform/src/version.js: -------------------------------------------------------------------------------- 1 | // Autogenerated by publish_packages.clj 2 | const version = 'v0.19.14-dev'; 3 | 4 | export default version; 5 | -------------------------------------------------------------------------------- /client/packages/platform/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.base.json", 3 | "include": ["src"], 4 | "exclude": ["node_modules", "dist"], 5 | "compilerOptions": { 6 | "strict": true, 7 | "outDir": "dist/tsc", 8 | "rewriteRelativeImportExtensions": true, 9 | "rootDir": "src", 10 | "checkJs": false, 11 | "skipLibCheck": true 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /client/packages/platform/vite.config.ts: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'vite'; 2 | import { resolve } from 'path'; 3 | 4 | export default defineConfig({ 5 | clearScreen: false, 6 | build: { 7 | outDir: 'dist/standalone', 8 | lib: { 9 | formats: ['umd', 'es'], 10 | // this is the file that exports our components 11 | entry: resolve(__dirname, 'src', 'index.ts'), 12 | name: 'instant', 13 | fileName: 'index', 14 | }, 15 | }, 16 | define: { 17 | 'process.env': {}, 18 | }, 19 | }); 20 | -------------------------------------------------------------------------------- /client/packages/react-native/.npmignore: -------------------------------------------------------------------------------- 1 | .turbo 2 | -------------------------------------------------------------------------------- /client/packages/react-native/src/NetworkListener.js: -------------------------------------------------------------------------------- 1 | import NetInfo from '@react-native-community/netinfo'; 2 | 3 | export default class NetworkListener { 4 | static async getIsOnline() { 5 | const network = await NetInfo.fetch(); 6 | return network.isConnected; 7 | } 8 | static listen(f) { 9 | return NetInfo.addEventListener((state) => { 10 | f(state.isConnected); 11 | }); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /client/packages/react-native/src/Storage.js: -------------------------------------------------------------------------------- 1 | import { IndexedDBStorage } from '@instantdb/core'; 2 | 3 | export default IndexedDBStorage; 4 | -------------------------------------------------------------------------------- /client/packages/react-native/src/Storage.native.js: -------------------------------------------------------------------------------- 1 | import AsyncStorage from '@react-native-async-storage/async-storage'; 2 | 3 | export default class Storage { 4 | constructor(dbName) { 5 | this.dbName = dbName; 6 | } 7 | 8 | async getItem(k) { 9 | return await AsyncStorage.getItem(`${this.dbName}_${k}`); 10 | } 11 | 12 | async setItem(k, v) { 13 | await AsyncStorage.setItem(`${this.dbName}_${k}`, v); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /client/packages/react-native/src/cli.ts: -------------------------------------------------------------------------------- 1 | export * from '@instantdb/core'; 2 | -------------------------------------------------------------------------------- /client/packages/react-native/src/version.js: -------------------------------------------------------------------------------- 1 | // Autogenerated by publish_packages.clj 2 | const version = 'v0.19.14-dev'; 3 | 4 | export default version; 5 | -------------------------------------------------------------------------------- /client/packages/react-native/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.base.json", 3 | "include": ["src"], 4 | "exclude": ["node_modules", "dist"], 5 | "compilerOptions": { 6 | "outDir": "dist", 7 | "rootDir": "src" 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /client/packages/react-native/tsconfig.module.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig", 3 | "compilerOptions": { 4 | "module": "es2015", 5 | "moduleResolution": "node", 6 | "outDir": "dist/module" 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /client/packages/react/.npmignore: -------------------------------------------------------------------------------- 1 | .turbo 2 | -------------------------------------------------------------------------------- /client/packages/react/__example__/standalone.umd.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Instant React UMD standalone example/test 7 | 8 | 9 | 13 | 17 | 18 | 19 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /client/packages/react/src/InstantReactWebDatabase.ts: -------------------------------------------------------------------------------- 1 | import type { InstantSchemaDef } from '@instantdb/core'; 2 | import InstantReactAbstractDatabase from './InstantReactAbstractDatabase.ts'; 3 | 4 | export default class InstantReactWebDatabase< 5 | Schema extends InstantSchemaDef, 6 | > extends InstantReactAbstractDatabase {} 7 | -------------------------------------------------------------------------------- /client/packages/react/src/useTimeout.ts: -------------------------------------------------------------------------------- 1 | import { useEffect, useRef } from 'react'; 2 | 3 | export function useTimeout() { 4 | const timeoutRef = useRef(null); 5 | 6 | useEffect(() => { 7 | clear(); 8 | }, []); 9 | 10 | function set(delay: number, fn: () => void) { 11 | clearTimeout(timeoutRef.current); 12 | timeoutRef.current = setTimeout(fn, delay); 13 | } 14 | 15 | function clear() { 16 | clearTimeout(timeoutRef.current); 17 | } 18 | 19 | return { set, clear }; 20 | } 21 | -------------------------------------------------------------------------------- /client/packages/react/src/version.js: -------------------------------------------------------------------------------- 1 | // Autogenerated by publish_packages.clj 2 | const version = 'v0.19.14-dev'; 3 | 4 | export default version; 5 | -------------------------------------------------------------------------------- /client/packages/react/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.base.json", 3 | "include": ["src"], 4 | "exclude": ["node_modules", "dist"], 5 | "compilerOptions": { 6 | "outDir": "dist/tsc", 7 | "rewriteRelativeImportExtensions": true, 8 | "rootDir": "src", 9 | "jsx": "react-jsx" 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /client/pnpm-workspace.yaml: -------------------------------------------------------------------------------- 1 | packages: 2 | - 'packages/*' 3 | - 'sandbox/*' 4 | - 'www' 5 | - 'www/_emails/replace-images' 6 | -------------------------------------------------------------------------------- /client/sandbox/admin-sdk-express/.env.example: -------------------------------------------------------------------------------- 1 | INSTANT_APP_ID= 2 | INSTANT_ADMIN_TOKEN= 3 | INSTANT_PERSONAL_ACCESS_TOKEN= 4 | -------------------------------------------------------------------------------- /client/sandbox/admin-sdk-express/README.md: -------------------------------------------------------------------------------- 1 |

2 | 3 | Shows the Instant logo 4 | 5 |

sandbox/admin-sdk-express

6 |

7 | 8 | This is sandbox app to play with [@instantdb/admin](../../packages/admin/). 9 | 10 | # Development 11 | 12 | First, let's set up your environment. Create an Instant app, either on your local backend or prod, and fill out the token info in your `.env` file. 13 | 14 | ```bash 15 | cp .env.example .env 16 | # fill in the variables in .env 17 | ``` 18 | 19 | With this, you can load [localhost:3005](http://localhost:3005) to see the admin server. 20 | 21 | # Questions? 22 | 23 | If you have any questions, feel free to drop us a line on our [Discord](https://discord.com/invite/VU53p7uQcE)! 24 | -------------------------------------------------------------------------------- /client/sandbox/admin-sdk-express/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "sandbox/admin-sdk-express", 3 | "version": "0.0.1", 4 | "description": "Test script for admin SDK", 5 | "type": "module", 6 | "scripts": { 7 | "dev": "node --watch --watch-preserve-output -r ts-node/register ./src/index.ts" 8 | }, 9 | "dependencies": { 10 | "@instantdb/admin": "workspace:*", 11 | "body-parser": "^1.20.2", 12 | "cors": "^2.8.5", 13 | "dotenv": "^16.3.1", 14 | "express": "^4.18.2", 15 | "node-fetch": "^3.3.2", 16 | "ts-node": "^10.9.2" 17 | }, 18 | "devDependencies": { 19 | "@types/body-parser": "^1.19.5", 20 | "@types/cors": "^2.8.17", 21 | "@types/express": "^4.17.21" 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /client/sandbox/admin-sdk-express/src/circle_blue.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/instantdb/instant/fd03a3aa4a0074e6d4a61eb522d435f43eba9655/client/sandbox/admin-sdk-express/src/circle_blue.jpg -------------------------------------------------------------------------------- /client/sandbox/cli-nodejs/.env.example: -------------------------------------------------------------------------------- 1 | INSTANT_APP_ID= 2 | INSTANT_SCHEMA_FILE_PATH=./src/db/instant.schema.ts 3 | INSTANT_PERMS_FILE_PATH=./src/db/instant.perms.ts 4 | -------------------------------------------------------------------------------- /client/sandbox/cli-nodejs/README.md: -------------------------------------------------------------------------------- 1 |

2 | 3 | Shows the Instant logo 4 | 5 |

sandbox/cli-nodejs

6 |

7 | 8 | This is sandbox app to play with [instant-cli](../../packages/cli/). 9 | 10 | # Development 11 | 12 | First, let's set up your environment. Create an Instant app, either on your local backend or prod, and fill out the token info in your `.env` file. 13 | 14 | ```bash 15 | cp .env.example .env 16 | # fill in the variables in .env 17 | ``` 18 | 19 | Once you do that, call instant-cli commands like so: 20 | 21 | ```bash 22 | INSTANT_CLI_DEV=1 pnpm exec instant-cli -h 23 | ``` 24 | 25 | # Questions? 26 | 27 | If you have any questions, feel free to drop us a line on our [Discord](https://discord.com/invite/VU53p7uQcE)! 28 | -------------------------------------------------------------------------------- /client/sandbox/cli-nodejs/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "sandbox/cli-nodejs", 3 | "private": true, 4 | "dependencies": { 5 | "@instantdb/admin": "workspace:*", 6 | "@instantdb/core": "workspace:*", 7 | "instant-cli": "workspace:*" 8 | }, 9 | "devDependencies": { 10 | "@types/node": "^22.5.0", 11 | "dotenv": "^16.3.1" 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /client/sandbox/cli-nodejs/src/db/instant.perms.ts: -------------------------------------------------------------------------------- 1 | export default { 2 | authors: { 3 | bind: ['isAuthor', 'auth.id == data.userId'], 4 | allow: { 5 | view: 'true', 6 | create: 'isAuthor', 7 | update: 'isAuthor', 8 | delete: 'isAuthor', 9 | }, 10 | }, 11 | posts: { 12 | bind: ['isAuthor', "auth.id in data.ref('authors.userId')"], 13 | allow: { 14 | view: 'true', 15 | create: 'isAuthor', 16 | update: 'isAuthor', 17 | delete: 'isAuthor', 18 | }, 19 | }, 20 | tags: { 21 | bind: ['isOwner', "auth.id in data.ref('posts.authors.userId')"], 22 | allow: { 23 | view: 'true', 24 | create: 'isOwner', 25 | update: 'isOwner', 26 | delete: 'isOwner', 27 | }, 28 | }, 29 | }; 30 | -------------------------------------------------------------------------------- /client/sandbox/cli-nodejs/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "types": ["node"], 4 | "target": "ES2020", 5 | "module": "ESNext", 6 | 7 | /* Bundler mode */ 8 | "moduleResolution": "node", 9 | "noEmit": true, 10 | 11 | /* Linting */ 12 | "strict": true 13 | }, 14 | "include": ["src/db/instant.schema.ts", "src/db/instant.perms.ts"] 15 | } 16 | -------------------------------------------------------------------------------- /client/sandbox/react-native-expo/.env.example: -------------------------------------------------------------------------------- 1 | EXPO_PUBLIC_INSTANT_APP_ID= 2 | -------------------------------------------------------------------------------- /client/sandbox/react-native-expo/.gitignore: -------------------------------------------------------------------------------- 1 | # Learn more https://docs.github.com/en/get-started/getting-started-with-git/ignoring-files 2 | 3 | # dependencies 4 | node_modules/ 5 | 6 | # Expo 7 | .expo/ 8 | dist/ 9 | web-build/ 10 | 11 | # Native 12 | *.orig.* 13 | *.jks 14 | *.p8 15 | *.p12 16 | *.key 17 | *.mobileprovision 18 | 19 | # Metro 20 | .metro-health-check* 21 | 22 | # debug 23 | npm-debug.* 24 | yarn-debug.* 25 | yarn-error.* 26 | 27 | # macOS 28 | .DS_Store 29 | *.pem 30 | 31 | # local env files 32 | .env*.local 33 | 34 | # typescript 35 | *.tsbuildinfo 36 | -------------------------------------------------------------------------------- /client/sandbox/react-native-expo/README.md: -------------------------------------------------------------------------------- 1 |

2 | 3 | Shows the Instant logo 4 | 5 |

sandbox/react-nextjs

6 |

7 | 8 | This is sandbox app to play with [@instantdb/react-native](../../packages/react-native/). 9 | 10 | # Development 11 | 12 | First, let's set up your environment. Create an Instant app, either on your local backend or prod, and fill out the token info in your `.env` file. 13 | 14 | ```bash 15 | cp .env.example .env 16 | # fill in the variables in .env 17 | ``` 18 | 19 | With that, you can start expo: 20 | 21 | ```bash 22 | npx expo start 23 | ``` 24 | 25 | # Questions? 26 | 27 | If you have any questions, feel free to drop us a line on our [Discord](https://discord.com/invite/VU53p7uQcE)! 28 | -------------------------------------------------------------------------------- /client/sandbox/react-native-expo/app.json: -------------------------------------------------------------------------------- 1 | { 2 | "expo": { 3 | "name": "expo-instant", 4 | "slug": "expo-instant", 5 | "scheme": "expo-instant", 6 | "version": "1.0.0", 7 | "orientation": "portrait", 8 | "icon": "./assets/icon.png", 9 | "userInterfaceStyle": "light", 10 | "splash": { 11 | "image": "./assets/splash.png", 12 | "resizeMode": "contain", 13 | "backgroundColor": "#ffffff" 14 | }, 15 | "assetBundlePatterns": ["**/*"], 16 | "ios": { 17 | "supportsTablet": true 18 | }, 19 | "android": { 20 | "adaptiveIcon": { 21 | "foregroundImage": "./assets/adaptive-icon.png", 22 | "backgroundColor": "#ffffff" 23 | } 24 | }, 25 | "web": { 26 | "favicon": "./assets/favicon.png" 27 | }, 28 | "plugins": ["expo-router"] 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /client/sandbox/react-native-expo/app/config.js: -------------------------------------------------------------------------------- 1 | export default { 2 | appId: process.env.EXPO_PUBLIC_INSTANT_APP_ID, 3 | apiURI: 'http://localhost:8888', 4 | websocketURI: 'ws://localhost:8888/runtime/session', 5 | verbose: true, 6 | }; 7 | -------------------------------------------------------------------------------- /client/sandbox/react-native-expo/assets/adaptive-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/instantdb/instant/fd03a3aa4a0074e6d4a61eb522d435f43eba9655/client/sandbox/react-native-expo/assets/adaptive-icon.png -------------------------------------------------------------------------------- /client/sandbox/react-native-expo/assets/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/instantdb/instant/fd03a3aa4a0074e6d4a61eb522d435f43eba9655/client/sandbox/react-native-expo/assets/favicon.png -------------------------------------------------------------------------------- /client/sandbox/react-native-expo/assets/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/instantdb/instant/fd03a3aa4a0074e6d4a61eb522d435f43eba9655/client/sandbox/react-native-expo/assets/icon.png -------------------------------------------------------------------------------- /client/sandbox/react-native-expo/assets/splash.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/instantdb/instant/fd03a3aa4a0074e6d4a61eb522d435f43eba9655/client/sandbox/react-native-expo/assets/splash.png -------------------------------------------------------------------------------- /client/sandbox/react-native-expo/babel.config.js: -------------------------------------------------------------------------------- 1 | module.exports = function (api) { 2 | api.cache(true); 3 | return { 4 | presets: ['babel-preset-expo'], 5 | plugins: ['nativewind/babel'], 6 | }; 7 | }; 8 | -------------------------------------------------------------------------------- /client/sandbox/react-native-expo/instant.perms.ts: -------------------------------------------------------------------------------- 1 | // Docs: https://www.instantdb.com/docs/permissions 2 | 3 | import type { InstantRules } from '@instantdb/react-native'; 4 | 5 | const rules = { 6 | /** 7 | * Welcome to Instant's permission system! 8 | * Right now your rules are empty. To start filling them in, check out the docs: 9 | * https://www.instantdb.com/docs/permissions 10 | * 11 | * Here's an example to give you a feel: 12 | * posts: { 13 | * allow: { 14 | * view: "true", 15 | * create: "isOwner", 16 | * update: "isOwner", 17 | * delete: "isOwner", 18 | * }, 19 | * bind: ["isOwner", "auth.id != null && auth.id == data.creatorId"], 20 | * }, 21 | */ 22 | $default: { 23 | allow: { 24 | $default: 'true', 25 | }, 26 | }, 27 | } satisfies InstantRules; 28 | 29 | export default rules; 30 | -------------------------------------------------------------------------------- /client/sandbox/react-native-expo/nativewind-env.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | -------------------------------------------------------------------------------- /client/sandbox/react-native-expo/postcss.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | plugins: { 3 | tailwindcss: {}, 4 | autoprefixer: {}, 5 | }, 6 | }; 7 | -------------------------------------------------------------------------------- /client/sandbox/react-native-expo/tailwind.config.js: -------------------------------------------------------------------------------- 1 | /** @type {import('tailwindcss').Config} */ 2 | module.exports = { 3 | content: ['./app/**/*.{js,jsx,ts,tsx}', './src/**/*.{js,jsx,ts,tsx}'], 4 | theme: { 5 | extend: {}, 6 | }, 7 | plugins: [], 8 | }; 9 | -------------------------------------------------------------------------------- /client/sandbox/react-native-expo/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "checkJs": true 4 | }, 5 | "extends": "expo/tsconfig.base" 6 | } 7 | -------------------------------------------------------------------------------- /client/sandbox/react-nextjs/.env.example: -------------------------------------------------------------------------------- 1 | NEXT_PUBLIC_INSTANT_APP_ID= 2 | -------------------------------------------------------------------------------- /client/sandbox/react-nextjs/.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | /.pnp 6 | .pnp.js 7 | 8 | # testing 9 | /coverage 10 | 11 | # next.js 12 | /.next/ 13 | /out/ 14 | 15 | # production 16 | /build 17 | 18 | # misc 19 | .DS_Store 20 | *.pem 21 | 22 | # debug 23 | npm-debug.log* 24 | yarn-debug.log* 25 | yarn-error.log* 26 | .pnpm-debug.log* 27 | 28 | # local env files 29 | .env*.local 30 | 31 | # vercel 32 | .vercel 33 | 34 | # typescript 35 | *.tsbuildinfo 36 | next-env.d.ts 37 | -------------------------------------------------------------------------------- /client/sandbox/react-nextjs/README.md: -------------------------------------------------------------------------------- 1 |

2 | 3 | Shows the Instant logo 4 | 5 |

sandbox/react-nextjs

6 |

7 | 8 | This is sandbox app to play with [@instantdb/react](../../packages/react/). 9 | 10 | # Development 11 | 12 | First, let's set up your environment. Create an Instant app, either on your local backend or prod, and fill out the token info in your `.env` file. 13 | 14 | ```bash 15 | cp .env.example .env 16 | # fill in the variables in .env 17 | ``` 18 | 19 | Once done, load [localhost:4000](http://localhost:4000), and you'll see a list of example apps. 20 | 21 | # Questions? 22 | 23 | If you have any questions, feel free to drop us a line on our [Discord](https://discord.com/invite/VU53p7uQcE)! 24 | -------------------------------------------------------------------------------- /client/sandbox/react-nextjs/app/layout.tsx: -------------------------------------------------------------------------------- 1 | import '../styles/globals.css'; 2 | 3 | export const metadata = { 4 | title: 'Next.js', 5 | description: 'Generated by Next.js', 6 | }; 7 | 8 | export default function RootLayout({ 9 | children, 10 | }: { 11 | children: React.ReactNode; 12 | }) { 13 | return ( 14 | 15 | {children} 16 | 17 | ); 18 | } 19 | -------------------------------------------------------------------------------- /client/sandbox/react-nextjs/app/play/check-admin-cache/page.tsx: -------------------------------------------------------------------------------- 1 | import { init } from '@instantdb/admin'; 2 | 3 | import config from '../../../config'; 4 | 5 | const db = init({ 6 | ...config, 7 | adminToken: process.env.INSTANT_ADMIN_TOKEN!, 8 | }); 9 | 10 | export const dynamic = 'force-dynamic'; 11 | 12 | export default async function Page() { 13 | const query = await db.query({ 14 | goals: {}, 15 | }); 16 | return ( 17 |
18 | We just made a query via the app router. Load this page twice. Confirm 19 | that you see it in your clojure server both times. By default, nextjs 20 | caches fetch. 21 | {JSON.stringify(query, null, 2)} 22 |
23 | ); 24 | } 25 | -------------------------------------------------------------------------------- /client/sandbox/react-nextjs/config.ts: -------------------------------------------------------------------------------- 1 | const isProd = 2 | typeof window !== 'undefined' 3 | ? Boolean(localStorage.getItem('prodBackend')) 4 | : false; 5 | 6 | const config = { 7 | apiURI: isProd ? 'https://api.instantdb.com' : 'http://localhost:8888', 8 | websocketURI: isProd 9 | ? 'wss://api.instantdb.com/runtime/session' 10 | : 'ws://localhost:8888/runtime/session', 11 | 12 | appId: process.env.NEXT_PUBLIC_INSTANT_APP_ID!, 13 | devtool: true, 14 | }; 15 | 16 | export default config; 17 | -------------------------------------------------------------------------------- /client/sandbox/react-nextjs/imgs/circle_blue.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/instantdb/instant/fd03a3aa4a0074e6d4a61eb522d435f43eba9655/client/sandbox/react-nextjs/imgs/circle_blue.jpg -------------------------------------------------------------------------------- /client/sandbox/react-nextjs/imgs/circle_green.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/instantdb/instant/fd03a3aa4a0074e6d4a61eb522d435f43eba9655/client/sandbox/react-nextjs/imgs/circle_green.jpg -------------------------------------------------------------------------------- /client/sandbox/react-nextjs/imgs/circle_red.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/instantdb/instant/fd03a3aa4a0074e6d4a61eb522d435f43eba9655/client/sandbox/react-nextjs/imgs/circle_red.jpg -------------------------------------------------------------------------------- /client/sandbox/react-nextjs/imgs/square_blue.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/instantdb/instant/fd03a3aa4a0074e6d4a61eb522d435f43eba9655/client/sandbox/react-nextjs/imgs/square_blue.jpg -------------------------------------------------------------------------------- /client/sandbox/react-nextjs/imgs/square_green.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/instantdb/instant/fd03a3aa4a0074e6d4a61eb522d435f43eba9655/client/sandbox/react-nextjs/imgs/square_green.jpg -------------------------------------------------------------------------------- /client/sandbox/react-nextjs/imgs/square_red.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/instantdb/instant/fd03a3aa4a0074e6d4a61eb522d435f43eba9655/client/sandbox/react-nextjs/imgs/square_red.jpg -------------------------------------------------------------------------------- /client/sandbox/react-nextjs/imgs/triangle_blue.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/instantdb/instant/fd03a3aa4a0074e6d4a61eb522d435f43eba9655/client/sandbox/react-nextjs/imgs/triangle_blue.jpg -------------------------------------------------------------------------------- /client/sandbox/react-nextjs/imgs/triangle_green.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/instantdb/instant/fd03a3aa4a0074e6d4a61eb522d435f43eba9655/client/sandbox/react-nextjs/imgs/triangle_green.jpg -------------------------------------------------------------------------------- /client/sandbox/react-nextjs/imgs/triangle_red.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/instantdb/instant/fd03a3aa4a0074e6d4a61eb522d435f43eba9655/client/sandbox/react-nextjs/imgs/triangle_red.jpg -------------------------------------------------------------------------------- /client/sandbox/react-nextjs/lib/files.ts: -------------------------------------------------------------------------------- 1 | import fs from 'fs'; 2 | 3 | export type File = { 4 | fileName: string; 5 | pathName: string; 6 | name: string; 7 | }; 8 | 9 | export function getPageRouterFiles(): File[] { 10 | return fs.readdirSync('./pages/play').map((fileName) => { 11 | const name = fileName.replace(/\.tsx$/, '').replace(/\.jsx$/, ''); 12 | const pathName = '/play/' + name; 13 | 14 | return { fileName, pathName, name }; 15 | }); 16 | } 17 | 18 | export function getAppRouterFiles(): File[] { 19 | return fs.readdirSync('./app/play').map((fileName) => { 20 | const name = fileName.replace(/\.tsx$/, '').replace(/\.jsx$/, ''); 21 | const pathName = '/play/' + name; 22 | 23 | return { fileName, pathName, name }; 24 | }); 25 | } 26 | -------------------------------------------------------------------------------- /client/sandbox/react-nextjs/next.config.js: -------------------------------------------------------------------------------- 1 | /** @type {import('next').NextConfig} */ 2 | module.exports = { 3 | reactStrictMode: false, 4 | }; 5 | -------------------------------------------------------------------------------- /client/sandbox/react-nextjs/pages/_app.tsx: -------------------------------------------------------------------------------- 1 | import '../styles/globals.css'; 2 | import type { AppProps } from 'next/app'; 3 | import config from '../config'; 4 | 5 | function MyApp({ Component, pageProps }: AppProps) { 6 | if (!config.appId) { 7 | return ( 8 |
9 |

10 | Welcome to the react-nextjs playground! 11 |

12 |

13 | In order to use the playground, you need to set up a you `.env` file 14 |

15 |

16 | Take a look at the{' '} 17 | 21 | sandbox/react-nextjs README 22 | {' '} 23 | to learn more 24 |

25 |
26 | ); 27 | } 28 | return ; 29 | } 30 | 31 | export default MyApp; 32 | -------------------------------------------------------------------------------- /client/sandbox/react-nextjs/pages/play/dev-devtool.tsx: -------------------------------------------------------------------------------- 1 | import { init } from '@instantdb/react'; 2 | import config from '../../config'; 3 | 4 | let appId = config.appId; 5 | 6 | if (typeof window !== 'undefined') { 7 | (window as any).DEV_DEVTOOL = true; 8 | 9 | const appIdParam = new URLSearchParams(location.search).get('app_id'); 10 | if (appIdParam) { 11 | appId = appIdParam; 12 | } 13 | } 14 | 15 | const db = init({ ...config, appId }); 16 | 17 | export default function () { 18 | return ( 19 |
20 | {Array.from({ length: 10 }).map((_, i) => ( 21 |
22 | Lorem ipsum dolor, sit amet consectetur adipisicing elit. Mollitia 23 | animi distinctio ex, facere sed error! Laudantium quis voluptatibus 24 | itaque ipsam! Mollitia iusto asperiores eligendi, esse cumque dolore 25 | sapiente vero perspiciatis. 26 |
27 | ))} 28 |
29 | ); 30 | } 31 | -------------------------------------------------------------------------------- /client/sandbox/react-nextjs/pages/play/hello-world-blank.tsx: -------------------------------------------------------------------------------- 1 | import { i, init } from '@instantdb/react'; 2 | import config from '../../config'; 3 | 4 | const schema = i.schema({ 5 | entities: { 6 | colors: i.entity({ color: i.string() }), 7 | }, 8 | }); 9 | 10 | const db = init({ ...config, schema }); 11 | 12 | function App() { 13 | return
; 14 | } 15 | 16 | function Main() { 17 | db.useQuery({ colors: {} }); 18 | 19 | return ( 20 |
21 |

Hello world

22 |

23 | Your app, on `localhost` 24 |

25 |
26 | ); 27 | } 28 | 29 | export default App; 30 | -------------------------------------------------------------------------------- /client/sandbox/react-nextjs/postcss.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | plugins: { 3 | tailwindcss: {}, 4 | autoprefixer: {}, 5 | }, 6 | }; 7 | -------------------------------------------------------------------------------- /client/sandbox/react-nextjs/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/instantdb/instant/fd03a3aa4a0074e6d4a61eb522d435f43eba9655/client/sandbox/react-nextjs/public/favicon.ico -------------------------------------------------------------------------------- /client/sandbox/react-nextjs/styles/globals.css: -------------------------------------------------------------------------------- 1 | @tailwind base; 2 | @tailwind components; 3 | @tailwind utilities; 4 | 5 | /* Litoe */ 6 | .drawer-enter { 7 | transform: translateX(100%); 8 | } 9 | 10 | .drawer-enter-active { 11 | transform: translateX(0); 12 | } 13 | 14 | .drawer-exit { 15 | transform: translateX(0); 16 | } 17 | 18 | .drawer-exit-active { 19 | transform: translateX(100%); 20 | } 21 | -------------------------------------------------------------------------------- /client/sandbox/react-nextjs/tailwind.config.js: -------------------------------------------------------------------------------- 1 | /** @type {import('tailwindcss').Config} */ 2 | module.exports = { 3 | content: [ 4 | './pages/**/*.{js,ts,jsx,tsx}', 5 | './components/**/*.{js,ts,jsx,tsx}', 6 | ], 7 | theme: { 8 | extend: {}, 9 | }, 10 | plugins: [require('@tailwindcss/forms')], 11 | }; 12 | -------------------------------------------------------------------------------- /client/sandbox/react-nextjs/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es5", 4 | "lib": ["dom", "dom.iterable", "esnext"], 5 | "allowJs": true, 6 | "skipLibCheck": true, 7 | "strict": true, 8 | "forceConsistentCasingInFileNames": true, 9 | "noEmit": true, 10 | "esModuleInterop": true, 11 | "module": "esnext", 12 | "moduleResolution": "node", 13 | "resolveJsonModule": true, 14 | "isolatedModules": true, 15 | "jsx": "preserve", 16 | "incremental": true, 17 | "checkJs": false, 18 | "plugins": [ 19 | { 20 | "name": "next" 21 | } 22 | ] 23 | }, 24 | "include": [ 25 | "next-env.d.ts", 26 | "**/*.ts", 27 | "**/*.tsx", 28 | "**/*.js", 29 | "**/*.jsx", 30 | ".next/types/**/*.ts" 31 | ], 32 | "exclude": ["node_modules"] 33 | } 34 | -------------------------------------------------------------------------------- /client/sandbox/strong-init-vite/.env.example: -------------------------------------------------------------------------------- 1 | VITE_INSTANT_APP_ID= 2 | -------------------------------------------------------------------------------- /client/sandbox/strong-init-vite/.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | pnpm-debug.log* 8 | lerna-debug.log* 9 | 10 | node_modules 11 | dist 12 | dist-ssr 13 | *.local 14 | 15 | # Editor directories and files 16 | .vscode/* 17 | !.vscode/extensions.json 18 | .idea 19 | .DS_Store 20 | *.suo 21 | *.ntvs* 22 | *.njsproj 23 | *.sln 24 | *.sw? 25 | -------------------------------------------------------------------------------- /client/sandbox/strong-init-vite/README.md: -------------------------------------------------------------------------------- 1 |

2 | 3 | Shows the Instant logo 4 | 5 |

sandbox/strong-init-vite

6 |

7 | 8 | This is sandbox app to play with strong-init. 9 | 10 | # Development 11 | 12 | First, let's set up your environment. Create an Instant app, either on your local backend or prod, and fill out the token info in your `.env` file. 13 | 14 | ```bash 15 | cp .env.example .env 16 | # fill in the variables in .env 17 | ``` 18 | 19 | Once done, load [localhost:5173](http://localhost:5173), and you'll see a basic example with auth. 20 | 21 | # Questions? 22 | 23 | If you have any questions, feel free to drop us a line on our [Discord](https://discord.com/invite/VU53p7uQcE)! 24 | -------------------------------------------------------------------------------- /client/sandbox/strong-init-vite/eslint.config.js: -------------------------------------------------------------------------------- 1 | import js from '@eslint/js'; 2 | import globals from 'globals'; 3 | import reactHooks from 'eslint-plugin-react-hooks'; 4 | import reactRefresh from 'eslint-plugin-react-refresh'; 5 | import tseslint from 'typescript-eslint'; 6 | 7 | export default tseslint.config( 8 | { ignores: ['dist'] }, 9 | { 10 | extends: [js.configs.recommended, ...tseslint.configs.recommended], 11 | files: ['**/*.{ts,tsx}'], 12 | languageOptions: { 13 | ecmaVersion: 2020, 14 | globals: globals.browser, 15 | }, 16 | plugins: { 17 | 'react-hooks': reactHooks, 18 | 'react-refresh': reactRefresh, 19 | }, 20 | rules: { 21 | ...reactHooks.configs.recommended.rules, 22 | 'react-refresh/only-export-components': [ 23 | 'warn', 24 | { allowConstantExport: true }, 25 | ], 26 | }, 27 | }, 28 | ); 29 | -------------------------------------------------------------------------------- /client/sandbox/strong-init-vite/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Vite + React + TS 8 | 9 | 10 |
11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /client/sandbox/strong-init-vite/instant.perms.ts: -------------------------------------------------------------------------------- 1 | // Docs: https://www.instantdb.com/docs/permissions 2 | 3 | import { type InstantRules } from '@instantdb/react'; 4 | 5 | const rules = { 6 | attrs: { 7 | allow: { 8 | create: 'false', 9 | }, 10 | }, 11 | } satisfies InstantRules; 12 | 13 | export default rules; 14 | -------------------------------------------------------------------------------- /client/sandbox/strong-init-vite/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "sandbox/strong-init-vite", 3 | "private": true, 4 | "version": "0.0.0", 5 | "type": "module", 6 | "scripts": { 7 | "dev": "vite", 8 | "lint": "eslint .", 9 | "preview": "vite preview" 10 | }, 11 | "dependencies": { 12 | "react": "18.3.1", 13 | "react-dom": "18.3.1", 14 | "@instantdb/react": "workspace:*", 15 | "@instantdb/react-native": "workspace:*", 16 | "@instantdb/admin": "workspace:*", 17 | "@instantdb/core": "workspace:*", 18 | "instant-cli": "workspace:*" 19 | }, 20 | "devDependencies": { 21 | "@eslint/js": "^9.13.0", 22 | "@types/react": "18.3.1", 23 | "@types/react-dom": "18.3.1", 24 | "@vitejs/plugin-react": "^4.3.3", 25 | "eslint": "^9.13.0", 26 | "eslint-plugin-react-hooks": "^5.0.0", 27 | "eslint-plugin-react-refresh": "^0.4.14", 28 | "globals": "^15.11.0", 29 | "typescript-eslint": "^8.30.0", 30 | "typescript": "^5.8.3", 31 | "vite": "^5.2.0" 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /client/sandbox/strong-init-vite/src/index.css: -------------------------------------------------------------------------------- 1 | :root { 2 | font-family: Inter, system-ui, Avenir, Helvetica, Arial, sans-serif; 3 | line-height: 1.5; 4 | font-weight: 400; 5 | font-synthesis: none; 6 | text-rendering: optimizeLegibility; 7 | -webkit-font-smoothing: antialiased; 8 | -moz-osx-font-smoothing: grayscale; 9 | } 10 | 11 | -------------------------------------------------------------------------------- /client/sandbox/strong-init-vite/src/main.tsx: -------------------------------------------------------------------------------- 1 | import { StrictMode } from 'react'; 2 | import { createRoot } from 'react-dom/client'; 3 | import './index.css'; 4 | import App from './App.tsx'; 5 | 6 | createRoot(document.getElementById('root')!).render( 7 | 8 | 9 | , 10 | ); 11 | -------------------------------------------------------------------------------- /client/sandbox/strong-init-vite/src/typescript_branded.tsx: -------------------------------------------------------------------------------- 1 | import { i, init } from '@instantdb/react'; 2 | 3 | type BusinessEmail = string & { readonly __brand: unique symbol }; 4 | 5 | const schema = i.schema({ 6 | entities: { 7 | leads: i.entity({ 8 | email: i.string(), 9 | }), 10 | }, 11 | }); 12 | 13 | const db = init({ 14 | appId: 'my-app-id', 15 | schema, 16 | }); 17 | 18 | const r = db.useQuery({ 19 | leads: {}, 20 | }); 21 | 22 | const x = r.data?.leads[0]; 23 | x; 24 | -------------------------------------------------------------------------------- /client/sandbox/strong-init-vite/src/vite-env.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | -------------------------------------------------------------------------------- /client/sandbox/strong-init-vite/tsconfig.app.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo", 4 | "target": "ES2020", 5 | "useDefineForClassFields": true, 6 | "lib": ["ES2020", "DOM", "DOM.Iterable"], 7 | "module": "ESNext", 8 | "skipLibCheck": true, 9 | 10 | /* Bundler mode */ 11 | "moduleResolution": "Bundler", 12 | "allowImportingTsExtensions": true, 13 | "isolatedModules": true, 14 | "moduleDetection": "force", 15 | "noEmit": true, 16 | "jsx": "react-jsx", 17 | 18 | /* Linting */ 19 | "strict": true, 20 | "noUnusedLocals": true, 21 | "noUnusedParameters": true, 22 | "noFallthroughCasesInSwitch": true, 23 | "noUncheckedSideEffectImports": true 24 | }, 25 | "include": ["src"] 26 | } 27 | -------------------------------------------------------------------------------- /client/sandbox/strong-init-vite/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "files": [], 3 | "references": [ 4 | { "path": "./tsconfig.app.json" }, 5 | { "path": "./tsconfig.node.json" } 6 | ] 7 | } 8 | -------------------------------------------------------------------------------- /client/sandbox/strong-init-vite/tsconfig.node.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.node.tsbuildinfo", 4 | "target": "ES2022", 5 | "lib": ["ES2023"], 6 | "module": "ESNext", 7 | "skipLibCheck": true, 8 | 9 | /* Bundler mode */ 10 | "moduleResolution": "Bundler", 11 | "allowImportingTsExtensions": true, 12 | "isolatedModules": true, 13 | "moduleDetection": "force", 14 | "noEmit": true, 15 | 16 | /* Linting */ 17 | "strict": true, 18 | "noUnusedLocals": true, 19 | "noUnusedParameters": true, 20 | "noFallthroughCasesInSwitch": true, 21 | "noUncheckedSideEffectImports": true 22 | }, 23 | "include": ["vite.config.ts"] 24 | } 25 | -------------------------------------------------------------------------------- /client/sandbox/strong-init-vite/vite.config.ts: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'vite'; 2 | import react from '@vitejs/plugin-react'; 3 | 4 | // https://vite.dev/config/ 5 | export default defineConfig({ 6 | clearScreen: false, 7 | logLevel: 'warn', 8 | plugins: [react()], 9 | server: { 10 | port: 3015, 11 | }, 12 | }); 13 | -------------------------------------------------------------------------------- /client/sandbox/vanilla-js-nuxt/.gitignore: -------------------------------------------------------------------------------- 1 | # Nuxt dev/build outputs 2 | .output 3 | .data 4 | .nuxt 5 | .nitro 6 | .cache 7 | dist 8 | 9 | # Node dependencies 10 | node_modules 11 | 12 | # Logs 13 | logs 14 | *.log 15 | 16 | # Misc 17 | .DS_Store 18 | .fleet 19 | .idea 20 | 21 | # Local env files 22 | .env 23 | .env.* 24 | !.env.example 25 | -------------------------------------------------------------------------------- /client/sandbox/vanilla-js-nuxt/app.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 24 | 25 | 33 | -------------------------------------------------------------------------------- /client/sandbox/vanilla-js-nuxt/nuxt.config.ts: -------------------------------------------------------------------------------- 1 | // https://nuxt.com/docs/api/configuration/nuxt-config 2 | export default defineNuxtConfig({ 3 | compatibilityDate: '2024-11-01', 4 | devtools: { enabled: true }, 5 | devServer: { 6 | port: 3060, 7 | }, 8 | telemetry: false, 9 | vite: { 10 | clearScreen: false, 11 | logLevel: 'warn', 12 | }, 13 | }); 14 | -------------------------------------------------------------------------------- /client/sandbox/vanilla-js-nuxt/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "sandbox/vanilla-js-nuxt", 3 | "private": true, 4 | "type": "module", 5 | "scripts": { 6 | "build": "nuxt build", 7 | "dev": "nuxt dev", 8 | "generate": "nuxt generate", 9 | "preview": "nuxt preview", 10 | "postinstall": "nuxt prepare" 11 | }, 12 | "dependencies": { 13 | "@instantdb/core": "workspace:*", 14 | "nuxt": "^3.17.0", 15 | "uuid": "^11.1.0", 16 | "vue": "^3.5.13" 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /client/sandbox/vanilla-js-nuxt/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/instantdb/instant/fd03a3aa4a0074e6d4a61eb522d435f43eba9655/client/sandbox/vanilla-js-nuxt/public/favicon.ico -------------------------------------------------------------------------------- /client/sandbox/vanilla-js-nuxt/public/robots.txt: -------------------------------------------------------------------------------- 1 | User-Agent: * 2 | Disallow: 3 | -------------------------------------------------------------------------------- /client/sandbox/vanilla-js-nuxt/server/api/createId.ts: -------------------------------------------------------------------------------- 1 | import { id as coreId } from '@instantdb/core'; 2 | 3 | export default defineEventHandler(async () => { 4 | try { 5 | console.log('core/id', coreId); 6 | 7 | return { coreId: coreId() }; 8 | } catch (error) { 9 | console.error('error:', error); 10 | return { error: error instanceof Error ? error.message : 'Unknown error' }; 11 | } 12 | }); 13 | -------------------------------------------------------------------------------- /client/sandbox/vanilla-js-nuxt/server/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../.nuxt/tsconfig.server.json" 3 | } 4 | -------------------------------------------------------------------------------- /client/sandbox/vanilla-js-nuxt/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | // https://nuxt.com/docs/guide/concepts/typescript 3 | "extends": "./.nuxt/tsconfig.json" 4 | } 5 | -------------------------------------------------------------------------------- /client/sandbox/vanilla-js-vite/.env.example: -------------------------------------------------------------------------------- 1 | VITE_INSTANT_APP_ID= 2 | -------------------------------------------------------------------------------- /client/sandbox/vanilla-js-vite/.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | pnpm-debug.log* 8 | lerna-debug.log* 9 | 10 | node_modules 11 | dist 12 | dist-ssr 13 | *.local 14 | 15 | # Editor directories and files 16 | .vscode/* 17 | !.vscode/extensions.json 18 | .idea 19 | .DS_Store 20 | *.suo 21 | *.ntvs* 22 | *.njsproj 23 | *.sln 24 | *.sw? 25 | -------------------------------------------------------------------------------- /client/sandbox/vanilla-js-vite/README.md: -------------------------------------------------------------------------------- 1 |

2 | 3 | Shows the Instant logo 4 | 5 |

sandbox/vanilla-js-vite

6 |

7 | 8 | This is sandbox app to play with [@instantdb/core](../../packages/core/). 9 | 10 | # Development 11 | 12 | First, let's set up your environment. Create an Instant app, either on your local backend or prod, and fill out the token info in your `.env` file. 13 | 14 | ```bash 15 | cp .env.example .env 16 | # fill in the variables in .env 17 | ``` 18 | 19 | Once done, load [localhost:5173](http://localhost:5173), and you'll see a basic example with auth. 20 | 21 | # Questions? 22 | 23 | If you have any questions, feel free to drop us a line on our [Discord](https://discord.com/invite/VU53p7uQcE)! 24 | -------------------------------------------------------------------------------- /client/sandbox/vanilla-js-vite/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Vite + TS 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /client/sandbox/vanilla-js-vite/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "sandbox/vanilla-js-vite", 3 | "private": true, 4 | "version": "0.0.0", 5 | "type": "module", 6 | "scripts": { 7 | "dev": "vite --clearScreen false", 8 | "build": "tsc && vite build", 9 | "preview": "vite preview" 10 | }, 11 | "devDependencies": { 12 | "@types/google.accounts": "^0.0.14", 13 | "typescript": "^5.8.3", 14 | "vite": "^5.2.0" 15 | }, 16 | "dependencies": { 17 | "@instantdb/core": "workspace:*" 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /client/sandbox/vanilla-js-vite/schema.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Vite + TS 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /client/sandbox/vanilla-js-vite/src/schema.ts: -------------------------------------------------------------------------------- 1 | import './style.css'; 2 | import { init, i, id } from '@instantdb/core'; 3 | 4 | const APP_ID = import.meta.env.VITE_INSTANT_APP_ID; 5 | 6 | const preEl = document.createElement('pre'); 7 | document.body.appendChild(preEl); 8 | 9 | const buttonEl = document.createElement('button'); 10 | buttonEl.innerText = 'Add'; 11 | buttonEl.onclick = () => { 12 | console.log(1); 13 | addTodo(`Todo ${Date.now()}`); 14 | }; 15 | document.body.appendChild(buttonEl); 16 | 17 | const db = init({ 18 | appId: APP_ID, 19 | schema: i.schema({ 20 | entities: { 21 | todos: i.entity({ 22 | title: i.string(), 23 | }), 24 | }, 25 | }), 26 | }); 27 | 28 | db.subscribeQuery( 29 | { 30 | todos: {}, 31 | }, 32 | (r) => { 33 | preEl.innerText = JSON.stringify({ r }, null, ' '); 34 | }, 35 | ); 36 | 37 | function addTodo(title: string) { 38 | db.transact( 39 | db.tx.todos[id()].update({ 40 | title, 41 | }), 42 | ); 43 | } 44 | -------------------------------------------------------------------------------- /client/sandbox/vanilla-js-vite/src/style.css: -------------------------------------------------------------------------------- 1 | :root { 2 | font-family: Inter, system-ui, Avenir, Helvetica, Arial, sans-serif; 3 | line-height: 1.5; 4 | font-weight: 400; 5 | 6 | font-synthesis: none; 7 | text-rendering: optimizeLegibility; 8 | -webkit-font-smoothing: antialiased; 9 | -moz-osx-font-smoothing: grayscale; 10 | } 11 | 12 | -------------------------------------------------------------------------------- /client/sandbox/vanilla-js-vite/src/vite-env.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | -------------------------------------------------------------------------------- /client/sandbox/vanilla-js-vite/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "ES2020", 4 | "useDefineForClassFields": true, 5 | "module": "ESNext", 6 | "lib": ["ES2020", "DOM", "DOM.Iterable"], 7 | "skipLibCheck": true, 8 | 9 | /* Bundler mode */ 10 | "moduleResolution": "bundler", 11 | "allowImportingTsExtensions": true, 12 | "resolveJsonModule": true, 13 | "isolatedModules": true, 14 | "noEmit": true, 15 | 16 | /* Linting */ 17 | "strict": true, 18 | "noUnusedLocals": true, 19 | "noUnusedParameters": true, 20 | "noFallthroughCasesInSwitch": true 21 | }, 22 | "include": ["src"] 23 | } 24 | -------------------------------------------------------------------------------- /client/sandbox/vanilla-js-vite/vie.config.ts: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'vite'; 2 | 3 | // https://vite.dev/config/ 4 | export default defineConfig({ 5 | clearScreen: false, 6 | logLevel: 'warn', 7 | }); 8 | -------------------------------------------------------------------------------- /client/tsconfig.base.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "declaration": true, 4 | "declarationMap": true, 5 | "module": "NodeNext", 6 | "moduleResolution": "nodenext", 7 | "sourceMap": true, 8 | "inlineSources": true, 9 | "target": "es2015", 10 | "esModuleInterop": true, 11 | "forceConsistentCasingInFileNames": true, 12 | "stripInternal": true, 13 | "allowSyntheticDefaultImports": true, 14 | "allowJs": true 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /client/turbo.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://turborepo.org/schema.json", 3 | "pipeline": { 4 | "build": { 5 | "dependsOn": ["^build"], 6 | "outputs": ["dist/**", ".next/**"] 7 | }, 8 | "publish-package": { 9 | "cache": false, 10 | "dependsOn": ["build", "^publish-package"], 11 | "outputs": [] 12 | }, 13 | "lint": { 14 | "outputs": [] 15 | }, 16 | "test:ci": { 17 | "outputs": [] 18 | }, 19 | "bench:ci": { 20 | "outputs": [] 21 | }, 22 | "dev": { 23 | "cache": false, 24 | "persistent": true 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /client/version.md: -------------------------------------------------------------------------------- 1 | v0.19.14 2 | -------------------------------------------------------------------------------- /client/www/.env: -------------------------------------------------------------------------------- 1 | NEXT_PUBLIC_FEEDBACK_APP_ID=5d9c6277-e6ac-42d6-8e51-2354b4870c05 2 | -------------------------------------------------------------------------------- /client/www/_emails/html/welcome_feb_2025.html: -------------------------------------------------------------------------------- 1 |

Hey there! Welcome to Instant! Full disclosure: this is an automated 2 | email, but if you respond, a real human (likely Joe or Stopa, the 3 | founders) will read it and get back to you.

4 |

How’s your experience with Instant been so far? Any feedback to 5 | share?

6 | -------------------------------------------------------------------------------- /client/www/_emails/markdown/welcome_feb_2025.md: -------------------------------------------------------------------------------- 1 | Hey there! Welcome to Instant! Full disclosure: this is an automated email, but 2 | if you respond, a real human (likely Joe or Stopa, the founders) will read it and get back to you. 3 | 4 | How's your experience with Instant been so far? Any feedback to share? 5 | -------------------------------------------------------------------------------- /client/www/_emails/replace-images/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "replace-images", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.mjs", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "keywords": [], 10 | "author": "", 11 | "license": "ISC", 12 | "dependencies": { 13 | "remark": "^15.0.1", 14 | "remark-parse": "^11.0.0", 15 | "remark-stringify": "^11.0.0", 16 | "unified": "^11.0.5" 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /client/www/_emails/txt/welcome_feb_2025.txt: -------------------------------------------------------------------------------- 1 | Hey there! Welcome to Instant! Full disclosure: this is an automated email, but 2 | if you respond, a real human (likely Joe or Stopa, the founders) will read it and get back to you. 3 | 4 | How's your experience with Instant been so far? Any feedback to share? 5 | -------------------------------------------------------------------------------- /client/www/_posts/conj.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 'Building a Sync Engine in Clojure [Video]' 3 | date: '2024-10-24' 4 | authors: nezaj 5 | --- 6 | 7 | [!video](https://www.youtube.com/watch?v=6FikTQf8qho 'Building a Sync Engine in Clojure') 8 | 9 | Following up from [A Graph-Based 10 | Firebase](https://www.instantdb.com/essays/next_firebase), Stopa (CTO of 11 | Instant), gave a talk about building Instant at Clojure Conj 2024! In this talk 12 | he discusses the common schleps developers face when building apps, and how 13 | Instant compresses them. 14 | 15 | Give this a watch if you’re interested in learning more about how Instant works under the hood! 16 | -------------------------------------------------------------------------------- /client/www/components/ErrorBoundary.tsx: -------------------------------------------------------------------------------- 1 | import { Component, PropsWithChildren } from 'react'; 2 | 3 | export class ErrorBoundary extends Component< 4 | PropsWithChildren<{ 5 | renderError: () => React.ReactNode; 6 | }>, 7 | { hasError: boolean } 8 | > { 9 | constructor(props: { renderError: () => React.ReactNode }) { 10 | super(props); 11 | this.state = { hasError: false }; 12 | } 13 | 14 | static getDerivedStateFromError(error: any) { 15 | return { hasError: true }; 16 | } 17 | 18 | componentDidCatch(error: any, errorInfo: any) { 19 | console.error(error, errorInfo); 20 | } 21 | 22 | render() { 23 | if (this.state.hasError) { 24 | return this.props.renderError(); 25 | } 26 | 27 | return this.props.children; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /client/www/components/clientOnlyPage.tsx: -------------------------------------------------------------------------------- 1 | import { useIsHydrated } from '@/lib/hooks/useIsHydrated'; 2 | import { NextRouter, useRouter } from 'next/router'; 3 | 4 | export function useReadyRouter(): Omit { 5 | const router = useRouter(); 6 | if (!router.isReady) { 7 | throw new Error( 8 | 'Router was not ready. Make sure to call this hook somewhere inside an `asClientOnlyPage` component', 9 | ); 10 | } 11 | return router; 12 | } 13 | 14 | export function asClientOnlyPage( 15 | Component: React.ComponentType, 16 | ) { 17 | return function ClientOnlyPage(props: Props) { 18 | const isHydrated = useIsHydrated(); 19 | const router = useRouter(); 20 | if (!isHydrated) { 21 | return null; 22 | } 23 | if (!router.isReady) { 24 | return null; 25 | } 26 | 27 | return ; 28 | }; 29 | } 30 | -------------------------------------------------------------------------------- /client/www/components/dash/shared.tsx: -------------------------------------------------------------------------------- 1 | export function Loading() { 2 | return ( 3 |
4 | ); 5 | } 6 | 7 | export function ErrorMessage({ children }: { children: React.ReactNode }) { 8 | return ( 9 |
10 |
{children}
11 |
12 | ); 13 | } 14 | -------------------------------------------------------------------------------- /client/www/components/docs/Ansi.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import AnsiToHtml from 'ansi-to-html'; 3 | 4 | const converter = new AnsiToHtml(); 5 | 6 | /** 7 | * You may be wondering, how do you actually get the ANSI text? 8 | * 9 | * Here's what you do: 10 | * 1. Open your terminal 11 | * 2. Run `script -q transcript.txt` to start recording your terminal session 12 | * 3. Run the commands you want to record 13 | * 4. `exit` to stop recording 14 | * 15 | * Once you do, open transcript.txt, and you'll see the ANSI text. 16 | */ 17 | export function Ansi({ children }) { 18 | const text = children.props.children; 19 | const html = converter.toHtml(text); 20 | 21 | return
;
22 | }
23 | 


--------------------------------------------------------------------------------
/client/www/components/docs/Button.jsx:
--------------------------------------------------------------------------------
 1 | import Link from 'next/link';
 2 | import clsx from 'clsx';
 3 | 
 4 | const styles = {
 5 |   primary:
 6 |     'rounded-full bg-sky-300 py-2 px-4 text-sm font-semibold text-slate-900 hover:bg-sky-200 focus:outline-none focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-sky-300/50 active:bg-sky-500',
 7 |   secondary:
 8 |     'rounded-full bg-slate-800 py-2 px-4 text-sm font-medium text-white hover:bg-slate-700 focus:outline-none focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-white/50 active:text-slate-400',
 9 | };
10 | 
11 | export function Button({ variant = 'primary', className, href, ...props }) {
12 |   className = clsx(styles[variant], className);
13 | 
14 |   return href ? (
15 |     
16 |   ) : (
17 |