├── .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 |
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 |
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 |
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 |
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 |
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 |
2 | call ID endpoint
3 | Server response:
4 | {{ JSON.stringify(response, null, 2) }}
5 |
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 |
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 |
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 |
18 | );
19 | }
20 |
--------------------------------------------------------------------------------
/client/www/components/docs/Logo.jsx:
--------------------------------------------------------------------------------
1 | export function Logo() {
2 | return (
3 |
4 |
5 |
6 | Instant
7 |
8 |
9 |
10 | );
11 | }
12 |
--------------------------------------------------------------------------------
/client/www/components/docs/Prose.jsx:
--------------------------------------------------------------------------------
1 | import clsx from 'clsx';
2 |
3 | export function Prose({ as: Component = 'div', className, ...props }) {
4 | return (
5 |
23 | );
24 | }
25 |
--------------------------------------------------------------------------------
/client/www/components/icons/VercelIcon.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 |
3 | const VercelIcon = React.forwardRef>(
4 | (props: React.ComponentProps<'svg'>, ref) => (
5 |
12 |
13 |
14 | ),
15 | );
16 |
17 | export default VercelIcon;
18 |
--------------------------------------------------------------------------------
/client/www/data/tutorial-snippets/todos-update-delete-instant.tsx:
--------------------------------------------------------------------------------
1 | // @ts-nocheck
2 | function deleteMessage(setMessages, messageId: string) {
3 | db.transact(db.tx.messages[messageId].delete());
4 | }
5 |
6 | function updateMessage(messageId: string, newText: string) {
7 | db.transact(db.tx.messages[messageId].update({ text: newText }));
8 | }
9 |
--------------------------------------------------------------------------------
/client/www/data/tutorial-snippets/todos-update-delete-react.tsx:
--------------------------------------------------------------------------------
1 | // @ts-nocheck
2 | function deleteMessage(setMessages, messageId: string) {
3 | setMessages((messages) =>
4 | messages.filter((message) => message.id !== messageId),
5 | );
6 | }
7 |
8 | function updateMessage(setMessages, messageId: string, newText: string) {
9 | setMessages((messages) =>
10 | messages.map((message) =>
11 | message.id === messageId ? { ...message, text: newText } : message,
12 | ),
13 | );
14 | }
15 |
--------------------------------------------------------------------------------
/client/www/examples.ts:
--------------------------------------------------------------------------------
1 | import fs from 'fs';
2 | import { capitalize } from 'lodash';
3 |
4 | export type File = {
5 | code: string;
6 | name: string;
7 | fileName: string;
8 | pathName: string;
9 | };
10 |
11 | export function getFiles(): File[] {
12 | return fs.readdirSync('./pages/examples').map((fileName) => {
13 | const pathName = fileName.replace(/\.tsx$/, '');
14 | const name = capitalize(pathName.slice(2).split('-').join(' '));
15 | const code = fs
16 | .readFileSync(`./pages/examples/${fileName}`, 'utf-8')
17 | .replaceAll(`__getAppId()`, `"__YOUR_APP_ID__"`)
18 | .split('\n')
19 | .filter((l) => l.indexOf('// hide-line') === -1)
20 | .join('\n');
21 |
22 | return { fileName, pathName, name, code };
23 | });
24 | }
25 |
--------------------------------------------------------------------------------
/client/www/lib/SelectedAppContext.ts:
--------------------------------------------------------------------------------
1 | import { createContext } from 'react';
2 |
3 | export const SelectedAppContext = createContext<{
4 | id: string;
5 | title: string;
6 | } | null>(null);
7 |
--------------------------------------------------------------------------------
/client/www/lib/app.tsx:
--------------------------------------------------------------------------------
1 | export function createdAtComparator(
2 | a: { created_at: string },
3 | b: { created_at: string },
4 | ) {
5 | if (a.created_at < b.created_at) {
6 | return 1;
7 | }
8 |
9 | if (a.created_at > b.created_at) {
10 | return -1;
11 | }
12 | return 0;
13 | }
14 |
--------------------------------------------------------------------------------
/client/www/lib/contexts.ts:
--------------------------------------------------------------------------------
1 | import { createContext } from 'react';
2 |
3 | export const TokenContext = createContext('');
4 |
--------------------------------------------------------------------------------
/client/www/lib/feedback/clientDB.ts:
--------------------------------------------------------------------------------
1 | import { init } from '@instantdb/react';
2 | import schema from './instant.schema';
3 | import config from '@/lib/config';
4 |
5 | const clientDB = init({
6 | appId: process.env.NEXT_PUBLIC_FEEDBACK_APP_ID!,
7 | schema,
8 | ...config,
9 | });
10 |
11 | export default clientDB;
12 |
--------------------------------------------------------------------------------
/client/www/lib/feedback/instant.schema.ts:
--------------------------------------------------------------------------------
1 | // Docs: https://www.instantdb.com/docs/modeling-data
2 |
3 | import { i, InstaQLEntity } from '@instantdb/react';
4 |
5 | const _schema = i.schema({
6 | entities: {
7 | ratings: i.entity({
8 | // Indexing so we can easily find all ratings for a page
9 | pageId: i.string().indexed(),
10 | localId: i.string(),
11 | // We'll use a unique key to make sure that a user
12 | // can only rate a particular page once.
13 | key: i.string().unique(),
14 | wasHelpful: i.boolean(),
15 | extraComment: i.string(),
16 | }),
17 | },
18 | links: {},
19 | rooms: {},
20 | });
21 |
22 | // This helps Typescript display nicer intellisense
23 | type _AppSchema = typeof _schema;
24 | interface AppSchema extends _AppSchema {}
25 | const schema: AppSchema = _schema;
26 |
27 | type Rating = InstaQLEntity;
28 |
29 | export type { AppSchema, Rating };
30 |
31 | export default schema;
32 |
--------------------------------------------------------------------------------
/client/www/lib/fetch.ts:
--------------------------------------------------------------------------------
1 | export async function jsonFetch(
2 | input: RequestInfo,
3 | init: RequestInit | undefined,
4 | ): Promise {
5 | const res = await fetch(input, init);
6 | const json = await res.json();
7 | return res.status === 200
8 | ? Promise.resolve(json)
9 | : Promise.reject({ status: res.status, body: json });
10 | }
11 |
12 | export async function jsonMutate(
13 | input: RequestInfo,
14 | {
15 | token,
16 | body,
17 | method,
18 | }: { token: string; body?: any; method?: 'POST' | 'DELETE' },
19 | ): Promise {
20 | return jsonFetch(input, {
21 | method: method ?? 'POST',
22 | headers: {
23 | authorization: `Bearer ${token}`,
24 | 'content-type': 'application/json',
25 | },
26 | body: body ? JSON.stringify(body) : undefined,
27 | });
28 | }
29 |
--------------------------------------------------------------------------------
/client/www/lib/flags.ts:
--------------------------------------------------------------------------------
1 | export const flags = {
2 | emails: false,
3 | } as const;
4 |
--------------------------------------------------------------------------------
/client/www/lib/format.ts:
--------------------------------------------------------------------------------
1 | export function formatBytes(bytes: number) {
2 | const units = ['bytes', 'kb', 'mb', 'gb', 'tb', 'pb', 'eb', 'zb', 'yb'];
3 | let index = 0;
4 |
5 | if (!bytes) return '0 bytes';
6 |
7 | while (bytes >= 1024 && index < units.length - 1) {
8 | bytes /= 1024;
9 | index++;
10 | }
11 |
12 | return bytes.toFixed(2) + ' ' + units[index];
13 | }
14 |
--------------------------------------------------------------------------------
/client/www/lib/hooks/useClickOutside.tsx:
--------------------------------------------------------------------------------
1 | import { RefObject, useEffect } from 'react';
2 |
3 | export function useClickOutside(
4 | ref: RefObject,
5 | callback: () => void,
6 | ) {
7 | const handleClick = (e: MouseEvent) => {
8 | if (
9 | ref.current &&
10 | e.target instanceof HTMLElement &&
11 | !ref.current.contains(e.target)
12 | ) {
13 | callback();
14 | }
15 | };
16 |
17 | useEffect(() => {
18 | document.addEventListener('click', handleClick);
19 | return () => {
20 | document.removeEventListener('click', handleClick);
21 | };
22 | });
23 | }
24 |
--------------------------------------------------------------------------------
/client/www/lib/hooks/useCurrentDate.tsx:
--------------------------------------------------------------------------------
1 | import { useEffect, useState } from 'react';
2 |
3 | export default function useCurrentDate({
4 | refreshSeconds,
5 | }: {
6 | refreshSeconds: number;
7 | }): Date {
8 | const [date, setDate] = useState(new Date());
9 | const refreshMs = refreshSeconds * 1000;
10 | useEffect(() => {
11 | const interval = setInterval(() => {
12 | setDate(new Date());
13 | }, refreshMs);
14 | return () => clearInterval(interval);
15 | }, [refreshMs]);
16 | return date;
17 | }
18 |
--------------------------------------------------------------------------------
/client/www/lib/hooks/useIsHydrated.tsx:
--------------------------------------------------------------------------------
1 | import { useEffect, useState } from 'react';
2 |
3 | export function useIsHydrated(): boolean {
4 | const [isHydrated, setIsHydrated] = useState(false);
5 |
6 | useEffect(() => {
7 | setIsHydrated(true);
8 | }, []);
9 |
10 | return isHydrated;
11 | }
12 |
--------------------------------------------------------------------------------
/client/www/lib/hooks/useIsOverflow.tsx:
--------------------------------------------------------------------------------
1 | import { useLayoutEffect, useRef, useState } from 'react';
2 |
3 | export function useIsOverflow() {
4 | const ref = useRef(null);
5 | const [isOverflow, setIsOverflow] = useState(false);
6 |
7 | useLayoutEffect(() => {
8 | const { current } = ref;
9 |
10 | const trigger = () => {
11 | const hasOverflow =
12 | current.scrollWidth > current.clientWidth ||
13 | current.scrollHeight > current.clientHeight;
14 |
15 | setIsOverflow(hasOverflow);
16 | };
17 |
18 | if (current) {
19 | trigger();
20 | }
21 | }, [ref]);
22 |
23 | return { ref, isOverflow };
24 | }
25 |
--------------------------------------------------------------------------------
/client/www/lib/og.ts:
--------------------------------------------------------------------------------
1 | export function url({ title, section }: { title?: string; section?: string }) {
2 | return `/api/og?title=${encodeURIComponent(title || '')}§ion=${section || ''}`;
3 | }
4 |
--------------------------------------------------------------------------------
/client/www/lib/url.tsx:
--------------------------------------------------------------------------------
1 | export function url(base: string, path: string, querty: Record) {
2 | const url = new URL(path, base);
3 | Object.entries(querty).forEach(([key, value]) => {
4 | if (value === undefined) return;
5 | url.searchParams.set(key, value);
6 | });
7 | return url.toString();
8 | }
9 |
10 | export function getQueryParam(param: string) {
11 | const urlParams = new URLSearchParams(window.location.search);
12 | return urlParams.get(param);
13 | }
14 |
--------------------------------------------------------------------------------
/client/www/markdoc/nodes.js:
--------------------------------------------------------------------------------
1 | import { Fence } from '@/components/docs/Fence';
2 |
3 | const nodes = {
4 | document: {
5 | render: undefined,
6 | },
7 | th: {
8 | attributes: {
9 | scope: {
10 | type: String,
11 | default: 'col',
12 | },
13 | },
14 | render: (props) => ,
15 | },
16 | fence: {
17 | render: Fence,
18 | attributes: {
19 | language: {
20 | type: String,
21 | },
22 | showCopy: {
23 | type: Boolean,
24 | },
25 | },
26 | },
27 | };
28 |
29 | export default nodes;
30 |
--------------------------------------------------------------------------------
/client/www/next-env.d.ts:
--------------------------------------------------------------------------------
1 | ///
2 | ///
3 |
4 | // NOTE: This file should not be edited
5 | // see https://nextjs.org/docs/pages/api-reference/config/typescript for more information.
6 |
--------------------------------------------------------------------------------
/client/www/next.config.js:
--------------------------------------------------------------------------------
1 | const withMarkdoc = require('@markdoc/next.js');
2 |
3 | /** @type {import('next').NextConfig} */
4 | const nextConfig = {
5 | reactStrictMode: true,
6 | pageExtensions: ['js', 'jsx', 'ts', 'tsx', 'md'],
7 | async redirects() {
8 | return [
9 | {
10 | permanent: false,
11 | source: '/',
12 | has: [
13 | {
14 | type: 'host',
15 | value: 'docs.instantdb.com',
16 | },
17 | ],
18 | destination: 'https://instantdb.com/docs/',
19 | },
20 | {
21 | permanent: false,
22 | source: '/:path*',
23 | has: [
24 | {
25 | type: 'host',
26 | value: 'docs.instantdb.com',
27 | },
28 | ],
29 | destination: 'https://instantdb.com/:path*',
30 | },
31 | ];
32 | },
33 | };
34 |
35 | module.exports = withMarkdoc()(nextConfig);
36 |
--------------------------------------------------------------------------------
/client/www/pages/404.tsx:
--------------------------------------------------------------------------------
1 | import { useEffect } from 'react';
2 | import { useRouter } from 'next/router';
3 | import { NextPage } from 'next';
4 |
5 | const Custom404: NextPage = () => {
6 | const router = useRouter();
7 |
8 | useEffect(() => {
9 | if (!router.isReady) return;
10 |
11 | const path = router.asPath;
12 |
13 | // Special case for docs, might make senses for other paths too, but figured
14 | // would keep it simple for now
15 | const redirectPath = path.includes('/docs') ? '/docs' : '/';
16 |
17 | router.replace(redirectPath);
18 | }, [router.isReady]);
19 |
20 | return null;
21 | };
22 |
23 | export default Custom404;
24 |
--------------------------------------------------------------------------------
/client/www/pages/_document.js:
--------------------------------------------------------------------------------
1 | import Document, { Html, Head, Main, NextScript } from 'next/document';
2 |
3 | class MyDocument extends Document {
4 | static async getInitialProps(ctx) {
5 | const initialProps = await Document.getInitialProps(ctx);
6 | return { ...initialProps };
7 | }
8 |
9 | render() {
10 | return (
11 |
12 |
13 |
14 |
15 |
19 |
20 |
21 |
22 |
23 |
24 |
25 | );
26 | }
27 | }
28 |
29 | export default MyDocument;
30 |
--------------------------------------------------------------------------------
/client/www/pages/examples/3-cursors.tsx:
--------------------------------------------------------------------------------
1 | import config from '@/lib/config'; // hide-line
2 | import { Cursors, init } from '@instantdb/react';
3 |
4 | const db = init({
5 | ...config, // hide-line
6 | appId: __getAppId(),
7 | });
8 |
9 | const room = db.room('cursors-example', '123');
10 |
11 | export default function InstantCursors() {
12 | return (
13 |
18 | Move your cursor around! ✨
19 |
20 | );
21 | }
22 |
23 | const randomDarkColor =
24 | '#' +
25 | [0, 0, 0]
26 | .map(() =>
27 | Math.floor(Math.random() * 200)
28 | .toString(16)
29 | .padStart(2, '0'),
30 | )
31 | .join('');
32 |
33 | const cursorsClassNames =
34 | 'flex h-screen w-screen items-center justify-center overflow-hidden font-mono text-sm text-gray-800 touch-none';
35 |
--------------------------------------------------------------------------------
/client/www/pages/intern/emails/index.tsx:
--------------------------------------------------------------------------------
1 | import { getAllSlugs } from '../../../lib/emails';
2 |
3 | export async function getStaticProps() {
4 | return {
5 | props: { slugs: getAllSlugs() },
6 | };
7 | }
8 |
9 | export default function Page({ slugs }: { slugs: String[] }) {
10 | return (
11 |
12 |
Slugs
13 |
14 | {slugs.map((e) => (
15 |
18 | ))}
19 |
20 |
21 | );
22 | }
23 |
--------------------------------------------------------------------------------
/client/www/pages/intern/signup.tsx:
--------------------------------------------------------------------------------
1 | import Head from 'next/head';
2 | import React from 'react';
3 | import AdminRoot from '../../components/admin/AdminRoot';
4 | import { useIsHydrated } from '@/lib/hooks/useIsHydrated';
5 |
6 | const AdminIndex = () => {
7 | const isHydrated = useIsHydrated();
8 | if (!isHydrated) return null;
9 | return (
10 |
11 |
12 |
Instant Dashboard
13 |
14 |
15 |
16 | );
17 | };
18 |
19 | export default AdminIndex;
20 |
--------------------------------------------------------------------------------
/client/www/postcss.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | plugins: {
3 | tailwindcss: {},
4 | autoprefixer: {},
5 | },
6 | };
7 |
--------------------------------------------------------------------------------
/client/www/public/fonts/BerkeleyMono-Bold.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/instantdb/instant/fd03a3aa4a0074e6d4a61eb522d435f43eba9655/client/www/public/fonts/BerkeleyMono-Bold.woff
--------------------------------------------------------------------------------
/client/www/public/fonts/BerkeleyMono-Bold.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/instantdb/instant/fd03a3aa4a0074e6d4a61eb522d435f43eba9655/client/www/public/fonts/BerkeleyMono-Bold.woff2
--------------------------------------------------------------------------------
/client/www/public/fonts/BerkeleyMono-BoldItalic.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/instantdb/instant/fd03a3aa4a0074e6d4a61eb522d435f43eba9655/client/www/public/fonts/BerkeleyMono-BoldItalic.woff
--------------------------------------------------------------------------------
/client/www/public/fonts/BerkeleyMono-BoldItalic.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/instantdb/instant/fd03a3aa4a0074e6d4a61eb522d435f43eba9655/client/www/public/fonts/BerkeleyMono-BoldItalic.woff2
--------------------------------------------------------------------------------
/client/www/public/fonts/BerkeleyMono-Italic.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/instantdb/instant/fd03a3aa4a0074e6d4a61eb522d435f43eba9655/client/www/public/fonts/BerkeleyMono-Italic.woff
--------------------------------------------------------------------------------
/client/www/public/fonts/BerkeleyMono-Italic.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/instantdb/instant/fd03a3aa4a0074e6d4a61eb522d435f43eba9655/client/www/public/fonts/BerkeleyMono-Italic.woff2
--------------------------------------------------------------------------------
/client/www/public/fonts/BerkeleyMono-Regular.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/instantdb/instant/fd03a3aa4a0074e6d4a61eb522d435f43eba9655/client/www/public/fonts/BerkeleyMono-Regular.woff
--------------------------------------------------------------------------------
/client/www/public/fonts/BerkeleyMono-Regular.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/instantdb/instant/fd03a3aa4a0074e6d4a61eb522d435f43eba9655/client/www/public/fonts/BerkeleyMono-Regular.woff2
--------------------------------------------------------------------------------
/client/www/public/fonts/BerkeleyMonoVariable-Italic.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/instantdb/instant/fd03a3aa4a0074e6d4a61eb522d435f43eba9655/client/www/public/fonts/BerkeleyMonoVariable-Italic.woff2
--------------------------------------------------------------------------------
/client/www/public/fonts/BerkeleyMonoVariable-Regular.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/instantdb/instant/fd03a3aa4a0074e6d4a61eb522d435f43eba9655/client/www/public/fonts/BerkeleyMonoVariable-Regular.woff2
--------------------------------------------------------------------------------
/client/www/public/img/docs/clerk-token-form.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/instantdb/instant/fd03a3aa4a0074e6d4a61eb522d435f43eba9655/client/www/public/img/docs/clerk-token-form.png
--------------------------------------------------------------------------------
/client/www/public/img/docs/devtool-explorer.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/instantdb/instant/fd03a3aa4a0074e6d4a61eb522d435f43eba9655/client/www/public/img/docs/devtool-explorer.png
--------------------------------------------------------------------------------
/client/www/public/img/docs/devtool-pointer.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/instantdb/instant/fd03a3aa4a0074e6d4a61eb522d435f43eba9655/client/www/public/img/docs/devtool-pointer.jpg
--------------------------------------------------------------------------------
/client/www/public/img/docs/devtool-sandbox.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/instantdb/instant/fd03a3aa4a0074e6d4a61eb522d435f43eba9655/client/www/public/img/docs/devtool-sandbox.png
--------------------------------------------------------------------------------
/client/www/public/img/docs/instaml-due-date.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/instantdb/instant/fd03a3aa4a0074e6d4a61eb522d435f43eba9655/client/www/public/img/docs/instaml-due-date.png
--------------------------------------------------------------------------------
/client/www/public/img/docs/instaql-data-intellisense.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/instantdb/instant/fd03a3aa4a0074e6d4a61eb522d435f43eba9655/client/www/public/img/docs/instaql-data-intellisense.png
--------------------------------------------------------------------------------
/client/www/public/img/docs/instaql-todos-goals-autocomplete.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/instantdb/instant/fd03a3aa4a0074e6d4a61eb522d435f43eba9655/client/www/public/img/docs/instaql-todos-goals-autocomplete.png
--------------------------------------------------------------------------------
/client/www/public/img/docs/modeling-data-rename-attr.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/instantdb/instant/fd03a3aa4a0074e6d4a61eb522d435f43eba9655/client/www/public/img/docs/modeling-data-rename-attr.png
--------------------------------------------------------------------------------
/client/www/public/img/docs/presence-intellisence.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/instantdb/instant/fd03a3aa4a0074e6d4a61eb522d435f43eba9655/client/www/public/img/docs/presence-intellisence.png
--------------------------------------------------------------------------------
/client/www/public/img/docs/rn-web-redirect-origins.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/instantdb/instant/fd03a3aa4a0074e6d4a61eb522d435f43eba9655/client/www/public/img/docs/rn-web-redirect-origins.png
--------------------------------------------------------------------------------
/client/www/public/img/emails/apr2025/s_A8BCE826E2D24A59DDDF978FF919F212AA1BA53C7F2773B4B244E2F70CDD846A_1746560157623_image.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/instantdb/instant/fd03a3aa4a0074e6d4a61eb522d435f43eba9655/client/www/public/img/emails/apr2025/s_A8BCE826E2D24A59DDDF978FF919F212AA1BA53C7F2773B4B244E2F70CDD846A_1746560157623_image.png
--------------------------------------------------------------------------------
/client/www/public/img/emails/apr2025/s_A8BCE826E2D24A59DDDF978FF919F212AA1BA53C7F2773B4B244E2F70CDD846A_1746560354137_image.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/instantdb/instant/fd03a3aa4a0074e6d4a61eb522d435f43eba9655/client/www/public/img/emails/apr2025/s_A8BCE826E2D24A59DDDF978FF919F212AA1BA53C7F2773B4B244E2F70CDD846A_1746560354137_image.png
--------------------------------------------------------------------------------
/client/www/public/img/emails/apr2025/s_A8BCE826E2D24A59DDDF978FF919F212AA1BA53C7F2773B4B244E2F70CDD846A_1746564212953_better-oauth.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/instantdb/instant/fd03a3aa4a0074e6d4a61eb522d435f43eba9655/client/www/public/img/emails/apr2025/s_A8BCE826E2D24A59DDDF978FF919F212AA1BA53C7F2773B4B244E2F70CDD846A_1746564212953_better-oauth.png
--------------------------------------------------------------------------------
/client/www/public/img/emails/apr2025/s_D5033FA557FFFE14A26ED3674BAE74F345ABE2D9051159D5B3634332C24375B3_1746466781941_CleanShot+2025-05-05+at+10.39.092x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/instantdb/instant/fd03a3aa4a0074e6d4a61eb522d435f43eba9655/client/www/public/img/emails/apr2025/s_D5033FA557FFFE14A26ED3674BAE74F345ABE2D9051159D5B3634332C24375B3_1746466781941_CleanShot+2025-05-05+at+10.39.092x.png
--------------------------------------------------------------------------------
/client/www/public/img/emails/apr2025/s_DF8F10A9009F2A236BC7D07C4EC05DDA50E4FB82F40AA98593D3B98A1A7EA3DC_1730238267270_instant_header.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/instantdb/instant/fd03a3aa4a0074e6d4a61eb522d435f43eba9655/client/www/public/img/emails/apr2025/s_DF8F10A9009F2A236BC7D07C4EC05DDA50E4FB82F40AA98593D3B98A1A7EA3DC_1730238267270_instant_header.png
--------------------------------------------------------------------------------
/client/www/public/img/emails/dec2024/s_A91D86B3D6F04CFEA63084B83C6E816ADC42104A6822CC9C6258E9D560CDF5F3_1735626509971_image.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/instantdb/instant/fd03a3aa4a0074e6d4a61eb522d435f43eba9655/client/www/public/img/emails/dec2024/s_A91D86B3D6F04CFEA63084B83C6E816ADC42104A6822CC9C6258E9D560CDF5F3_1735626509971_image.png
--------------------------------------------------------------------------------
/client/www/public/img/emails/dec2024/s_A91D86B3D6F04CFEA63084B83C6E816ADC42104A6822CC9C6258E9D560CDF5F3_1735626771452_image.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/instantdb/instant/fd03a3aa4a0074e6d4a61eb522d435f43eba9655/client/www/public/img/emails/dec2024/s_A91D86B3D6F04CFEA63084B83C6E816ADC42104A6822CC9C6258E9D560CDF5F3_1735626771452_image.png
--------------------------------------------------------------------------------
/client/www/public/img/emails/dec2024/s_A91D86B3D6F04CFEA63084B83C6E816ADC42104A6822CC9C6258E9D560CDF5F3_1735627523303_image.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/instantdb/instant/fd03a3aa4a0074e6d4a61eb522d435f43eba9655/client/www/public/img/emails/dec2024/s_A91D86B3D6F04CFEA63084B83C6E816ADC42104A6822CC9C6258E9D560CDF5F3_1735627523303_image.png
--------------------------------------------------------------------------------
/client/www/public/img/emails/dec2024/s_DF8F10A9009F2A236BC7D07C4EC05DDA50E4FB82F40AA98593D3B98A1A7EA3DC_1730238267270_instant_header.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/instantdb/instant/fd03a3aa4a0074e6d4a61eb522d435f43eba9655/client/www/public/img/emails/dec2024/s_DF8F10A9009F2A236BC7D07C4EC05DDA50E4FB82F40AA98593D3B98A1A7EA3DC_1730238267270_instant_header.png
--------------------------------------------------------------------------------
/client/www/public/img/emails/feb2025/s_513F5FE60B9BB3BB9CCD1CA54DF394804C0DE8F72ED1A4C65882EB8C31D175AE_1740786465619_add-links.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/instantdb/instant/fd03a3aa4a0074e6d4a61eb522d435f43eba9655/client/www/public/img/emails/feb2025/s_513F5FE60B9BB3BB9CCD1CA54DF394804C0DE8F72ED1A4C65882EB8C31D175AE_1740786465619_add-links.png
--------------------------------------------------------------------------------
/client/www/public/img/emails/feb2025/s_513F5FE60B9BB3BB9CCD1CA54DF394804C0DE8F72ED1A4C65882EB8C31D175AE_1740787113300_image.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/instantdb/instant/fd03a3aa4a0074e6d4a61eb522d435f43eba9655/client/www/public/img/emails/feb2025/s_513F5FE60B9BB3BB9CCD1CA54DF394804C0DE8F72ED1A4C65882EB8C31D175AE_1740787113300_image.png
--------------------------------------------------------------------------------
/client/www/public/img/emails/feb2025/s_513F5FE60B9BB3BB9CCD1CA54DF394804C0DE8F72ED1A4C65882EB8C31D175AE_1741040505548_image.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/instantdb/instant/fd03a3aa4a0074e6d4a61eb522d435f43eba9655/client/www/public/img/emails/feb2025/s_513F5FE60B9BB3BB9CCD1CA54DF394804C0DE8F72ED1A4C65882EB8C31D175AE_1741040505548_image.png
--------------------------------------------------------------------------------
/client/www/public/img/emails/feb2025/s_513F5FE60B9BB3BB9CCD1CA54DF394804C0DE8F72ED1A4C65882EB8C31D175AE_1741044653859_cascade.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/instantdb/instant/fd03a3aa4a0074e6d4a61eb522d435f43eba9655/client/www/public/img/emails/feb2025/s_513F5FE60B9BB3BB9CCD1CA54DF394804C0DE8F72ED1A4C65882EB8C31D175AE_1741044653859_cascade.png
--------------------------------------------------------------------------------
/client/www/public/img/emails/feb2025/s_DF8F10A9009F2A236BC7D07C4EC05DDA50E4FB82F40AA98593D3B98A1A7EA3DC_1730238267270_instant_header.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/instantdb/instant/fd03a3aa4a0074e6d4a61eb522d435f43eba9655/client/www/public/img/emails/feb2025/s_DF8F10A9009F2A236BC7D07C4EC05DDA50E4FB82F40AA98593D3B98A1A7EA3DC_1730238267270_instant_header.png
--------------------------------------------------------------------------------
/client/www/public/img/emails/mar2025/s_7B280E1A3BA8AB078D69579372DCD7F97D2F02F6D857FBABC05C42A70756AC62_1743727283805_image.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/instantdb/instant/fd03a3aa4a0074e6d4a61eb522d435f43eba9655/client/www/public/img/emails/mar2025/s_7B280E1A3BA8AB078D69579372DCD7F97D2F02F6D857FBABC05C42A70756AC62_1743727283805_image.png
--------------------------------------------------------------------------------
/client/www/public/img/emails/mar2025/s_7B280E1A3BA8AB078D69579372DCD7F97D2F02F6D857FBABC05C42A70756AC62_1743728983960_CleanShot+2025-04-03+at+18.09.332x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/instantdb/instant/fd03a3aa4a0074e6d4a61eb522d435f43eba9655/client/www/public/img/emails/mar2025/s_7B280E1A3BA8AB078D69579372DCD7F97D2F02F6D857FBABC05C42A70756AC62_1743728983960_CleanShot+2025-04-03+at+18.09.332x.png
--------------------------------------------------------------------------------
/client/www/public/img/emails/mar2025/s_7B280E1A3BA8AB078D69579372DCD7F97D2F02F6D857FBABC05C42A70756AC62_1743788878099_image.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/instantdb/instant/fd03a3aa4a0074e6d4a61eb522d435f43eba9655/client/www/public/img/emails/mar2025/s_7B280E1A3BA8AB078D69579372DCD7F97D2F02F6D857FBABC05C42A70756AC62_1743788878099_image.png
--------------------------------------------------------------------------------
/client/www/public/img/emails/mar2025/s_7B280E1A3BA8AB078D69579372DCD7F97D2F02F6D857FBABC05C42A70756AC62_1744060894895_instant_hero.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/instantdb/instant/fd03a3aa4a0074e6d4a61eb522d435f43eba9655/client/www/public/img/emails/mar2025/s_7B280E1A3BA8AB078D69579372DCD7F97D2F02F6D857FBABC05C42A70756AC62_1744060894895_instant_hero.jpeg
--------------------------------------------------------------------------------
/client/www/public/img/emails/mar2025/s_DF8F10A9009F2A236BC7D07C4EC05DDA50E4FB82F40AA98593D3B98A1A7EA3DC_1730238267270_instant_header.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/instantdb/instant/fd03a3aa4a0074e6d4a61eb522d435f43eba9655/client/www/public/img/emails/mar2025/s_DF8F10A9009F2A236BC7D07C4EC05DDA50E4FB82F40AA98593D3B98A1A7EA3DC_1730238267270_instant_header.png
--------------------------------------------------------------------------------
/client/www/public/img/emails/nov2024/s_B097BA2FA68FBDBEF71F30F95558A3D23729AED0A557430F53FE49A682293BBC_1733449686289_image.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/instantdb/instant/fd03a3aa4a0074e6d4a61eb522d435f43eba9655/client/www/public/img/emails/nov2024/s_B097BA2FA68FBDBEF71F30F95558A3D23729AED0A557430F53FE49A682293BBC_1733449686289_image.png
--------------------------------------------------------------------------------
/client/www/public/img/emails/nov2024/s_B097BA2FA68FBDBEF71F30F95558A3D23729AED0A557430F53FE49A682293BBC_1733450241867_image.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/instantdb/instant/fd03a3aa4a0074e6d4a61eb522d435f43eba9655/client/www/public/img/emails/nov2024/s_B097BA2FA68FBDBEF71F30F95558A3D23729AED0A557430F53FE49A682293BBC_1733450241867_image.png
--------------------------------------------------------------------------------
/client/www/public/img/emails/nov2024/s_B097BA2FA68FBDBEF71F30F95558A3D23729AED0A557430F53FE49A682293BBC_1733450981289_image.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/instantdb/instant/fd03a3aa4a0074e6d4a61eb522d435f43eba9655/client/www/public/img/emails/nov2024/s_B097BA2FA68FBDBEF71F30F95558A3D23729AED0A557430F53FE49A682293BBC_1733450981289_image.png
--------------------------------------------------------------------------------
/client/www/public/img/emails/nov2024/s_B097BA2FA68FBDBEF71F30F95558A3D23729AED0A557430F53FE49A682293BBC_1733451107349_image.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/instantdb/instant/fd03a3aa4a0074e6d4a61eb522d435f43eba9655/client/www/public/img/emails/nov2024/s_B097BA2FA68FBDBEF71F30F95558A3D23729AED0A557430F53FE49A682293BBC_1733451107349_image.png
--------------------------------------------------------------------------------
/client/www/public/img/emails/nov2024/s_B097BA2FA68FBDBEF71F30F95558A3D23729AED0A557430F53FE49A682293BBC_1733451831476_image.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/instantdb/instant/fd03a3aa4a0074e6d4a61eb522d435f43eba9655/client/www/public/img/emails/nov2024/s_B097BA2FA68FBDBEF71F30F95558A3D23729AED0A557430F53FE49A682293BBC_1733451831476_image.png
--------------------------------------------------------------------------------
/client/www/public/img/emails/nov2024/s_DF8F10A9009F2A236BC7D07C4EC05DDA50E4FB82F40AA98593D3B98A1A7EA3DC_1730238267270_instant_header.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/instantdb/instant/fd03a3aa4a0074e6d4a61eb522d435f43eba9655/client/www/public/img/emails/nov2024/s_DF8F10A9009F2A236BC7D07C4EC05DDA50E4FB82F40AA98593D3B98A1A7EA3DC_1730238267270_instant_header.png
--------------------------------------------------------------------------------
/client/www/public/img/emails/oct2024/s_B8A06116D3803694CDA0C13F9F97E92EA0220D4E377317F0F00D7831E3E41E9E_1727988124731_image.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/instantdb/instant/fd03a3aa4a0074e6d4a61eb522d435f43eba9655/client/www/public/img/emails/oct2024/s_B8A06116D3803694CDA0C13F9F97E92EA0220D4E377317F0F00D7831E3E41E9E_1727988124731_image.png
--------------------------------------------------------------------------------
/client/www/public/img/emails/oct2024/s_DF8F10A9009F2A236BC7D07C4EC05DDA50E4FB82F40AA98593D3B98A1A7EA3DC_1729122912083_image.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/instantdb/instant/fd03a3aa4a0074e6d4a61eb522d435f43eba9655/client/www/public/img/emails/oct2024/s_DF8F10A9009F2A236BC7D07C4EC05DDA50E4FB82F40AA98593D3B98A1A7EA3DC_1729122912083_image.png
--------------------------------------------------------------------------------
/client/www/public/img/emails/oct2024/s_DF8F10A9009F2A236BC7D07C4EC05DDA50E4FB82F40AA98593D3B98A1A7EA3DC_1729123513053_image.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/instantdb/instant/fd03a3aa4a0074e6d4a61eb522d435f43eba9655/client/www/public/img/emails/oct2024/s_DF8F10A9009F2A236BC7D07C4EC05DDA50E4FB82F40AA98593D3B98A1A7EA3DC_1729123513053_image.png
--------------------------------------------------------------------------------
/client/www/public/img/emails/oct2024/s_DF8F10A9009F2A236BC7D07C4EC05DDA50E4FB82F40AA98593D3B98A1A7EA3DC_1730238267270_instant_header.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/instantdb/instant/fd03a3aa4a0074e6d4a61eb522d435f43eba9655/client/www/public/img/emails/oct2024/s_DF8F10A9009F2A236BC7D07C4EC05DDA50E4FB82F40AA98593D3B98A1A7EA3DC_1730238267270_instant_header.png
--------------------------------------------------------------------------------
/client/www/public/img/emails/oct2024/s_DF8F10A9009F2A236BC7D07C4EC05DDA50E4FB82F40AA98593D3B98A1A7EA3DC_1730244001267_image.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/instantdb/instant/fd03a3aa4a0074e6d4a61eb522d435f43eba9655/client/www/public/img/emails/oct2024/s_DF8F10A9009F2A236BC7D07C4EC05DDA50E4FB82F40AA98593D3B98A1A7EA3DC_1730244001267_image.png
--------------------------------------------------------------------------------
/client/www/public/img/emails/oct2024/s_DF8F10A9009F2A236BC7D07C4EC05DDA50E4FB82F40AA98593D3B98A1A7EA3DC_1730244149277_users_table.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/instantdb/instant/fd03a3aa4a0074e6d4a61eb522d435f43eba9655/client/www/public/img/emails/oct2024/s_DF8F10A9009F2A236BC7D07C4EC05DDA50E4FB82F40AA98593D3B98A1A7EA3DC_1730244149277_users_table.png
--------------------------------------------------------------------------------
/client/www/public/img/google_g.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/client/www/public/img/hiring/backend.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/instantdb/instant/fd03a3aa4a0074e6d4a61eb522d435f43eba9655/client/www/public/img/hiring/backend.png
--------------------------------------------------------------------------------
/client/www/public/img/hiring/explorer.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/instantdb/instant/fd03a3aa4a0074e6d4a61eb522d435f43eba9655/client/www/public/img/hiring/explorer.png
--------------------------------------------------------------------------------
/client/www/public/img/hiring/sandbox.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/instantdb/instant/fd03a3aa4a0074e6d4a61eb522d435f43eba9655/client/www/public/img/hiring/sandbox.png
--------------------------------------------------------------------------------
/client/www/public/img/hiring/sync_engine.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/instantdb/instant/fd03a3aa4a0074e6d4a61eb522d435f43eba9655/client/www/public/img/hiring/sync_engine.png
--------------------------------------------------------------------------------
/client/www/public/img/icon/android-chrome-192x192.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/instantdb/instant/fd03a3aa4a0074e6d4a61eb522d435f43eba9655/client/www/public/img/icon/android-chrome-192x192.png
--------------------------------------------------------------------------------
/client/www/public/img/icon/android-chrome-512x512.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/instantdb/instant/fd03a3aa4a0074e6d4a61eb522d435f43eba9655/client/www/public/img/icon/android-chrome-512x512.png
--------------------------------------------------------------------------------
/client/www/public/img/icon/apple-touch-icon-114x114.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/instantdb/instant/fd03a3aa4a0074e6d4a61eb522d435f43eba9655/client/www/public/img/icon/apple-touch-icon-114x114.png
--------------------------------------------------------------------------------
/client/www/public/img/icon/apple-touch-icon-120x120.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/instantdb/instant/fd03a3aa4a0074e6d4a61eb522d435f43eba9655/client/www/public/img/icon/apple-touch-icon-120x120.png
--------------------------------------------------------------------------------
/client/www/public/img/icon/apple-touch-icon-144x144.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/instantdb/instant/fd03a3aa4a0074e6d4a61eb522d435f43eba9655/client/www/public/img/icon/apple-touch-icon-144x144.png
--------------------------------------------------------------------------------
/client/www/public/img/icon/apple-touch-icon-152x152.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/instantdb/instant/fd03a3aa4a0074e6d4a61eb522d435f43eba9655/client/www/public/img/icon/apple-touch-icon-152x152.png
--------------------------------------------------------------------------------
/client/www/public/img/icon/apple-touch-icon-167x167.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/instantdb/instant/fd03a3aa4a0074e6d4a61eb522d435f43eba9655/client/www/public/img/icon/apple-touch-icon-167x167.png
--------------------------------------------------------------------------------
/client/www/public/img/icon/apple-touch-icon-180x180.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/instantdb/instant/fd03a3aa4a0074e6d4a61eb522d435f43eba9655/client/www/public/img/icon/apple-touch-icon-180x180.png
--------------------------------------------------------------------------------
/client/www/public/img/icon/apple-touch-icon-57x57.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/instantdb/instant/fd03a3aa4a0074e6d4a61eb522d435f43eba9655/client/www/public/img/icon/apple-touch-icon-57x57.png
--------------------------------------------------------------------------------
/client/www/public/img/icon/apple-touch-icon-60x60.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/instantdb/instant/fd03a3aa4a0074e6d4a61eb522d435f43eba9655/client/www/public/img/icon/apple-touch-icon-60x60.png
--------------------------------------------------------------------------------
/client/www/public/img/icon/apple-touch-icon-72x72.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/instantdb/instant/fd03a3aa4a0074e6d4a61eb522d435f43eba9655/client/www/public/img/icon/apple-touch-icon-72x72.png
--------------------------------------------------------------------------------
/client/www/public/img/icon/apple-touch-icon-76x76.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/instantdb/instant/fd03a3aa4a0074e6d4a61eb522d435f43eba9655/client/www/public/img/icon/apple-touch-icon-76x76.png
--------------------------------------------------------------------------------
/client/www/public/img/icon/favicon-128x128.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/instantdb/instant/fd03a3aa4a0074e6d4a61eb522d435f43eba9655/client/www/public/img/icon/favicon-128x128.png
--------------------------------------------------------------------------------
/client/www/public/img/icon/favicon-16x16.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/instantdb/instant/fd03a3aa4a0074e6d4a61eb522d435f43eba9655/client/www/public/img/icon/favicon-16x16.png
--------------------------------------------------------------------------------
/client/www/public/img/icon/favicon-196x196.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/instantdb/instant/fd03a3aa4a0074e6d4a61eb522d435f43eba9655/client/www/public/img/icon/favicon-196x196.png
--------------------------------------------------------------------------------
/client/www/public/img/icon/favicon-32x32.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/instantdb/instant/fd03a3aa4a0074e6d4a61eb522d435f43eba9655/client/www/public/img/icon/favicon-32x32.png
--------------------------------------------------------------------------------
/client/www/public/img/icon/favicon-96x96.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/client/www/public/img/icon/logo-512.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/client/www/public/img/icon/mstile-144x144.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/instantdb/instant/fd03a3aa4a0074e6d4a61eb522d435f43eba9655/client/www/public/img/icon/mstile-144x144.png
--------------------------------------------------------------------------------
/client/www/public/img/icon/mstile-150x150.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/instantdb/instant/fd03a3aa4a0074e6d4a61eb522d435f43eba9655/client/www/public/img/icon/mstile-150x150.png
--------------------------------------------------------------------------------
/client/www/public/img/icon/mstile-310x150.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/instantdb/instant/fd03a3aa4a0074e6d4a61eb522d435f43eba9655/client/www/public/img/icon/mstile-310x150.png
--------------------------------------------------------------------------------
/client/www/public/img/icon/mstile-310x310.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/instantdb/instant/fd03a3aa4a0074e6d4a61eb522d435f43eba9655/client/www/public/img/icon/mstile-310x310.png
--------------------------------------------------------------------------------
/client/www/public/img/icon/mstile-70x70.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/instantdb/instant/fd03a3aa4a0074e6d4a61eb522d435f43eba9655/client/www/public/img/icon/mstile-70x70.png
--------------------------------------------------------------------------------
/client/www/public/img/og_preview.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/instantdb/instant/fd03a3aa4a0074e6d4a61eb522d435f43eba9655/client/www/public/img/og_preview.png
--------------------------------------------------------------------------------
/client/www/public/img/peeps/aj_nandi.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/instantdb/instant/fd03a3aa4a0074e6d4a61eb522d435f43eba9655/client/www/public/img/peeps/aj_nandi.jpeg
--------------------------------------------------------------------------------
/client/www/public/img/peeps/alex.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/instantdb/instant/fd03a3aa4a0074e6d4a61eb522d435f43eba9655/client/www/public/img/peeps/alex.png
--------------------------------------------------------------------------------
/client/www/public/img/peeps/hunter.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/instantdb/instant/fd03a3aa4a0074e6d4a61eb522d435f43eba9655/client/www/public/img/peeps/hunter.jpeg
--------------------------------------------------------------------------------
/client/www/public/img/peeps/james.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/instantdb/instant/fd03a3aa4a0074e6d4a61eb522d435f43eba9655/client/www/public/img/peeps/james.png
--------------------------------------------------------------------------------
/client/www/public/img/peeps/nacho.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/instantdb/instant/fd03a3aa4a0074e6d4a61eb522d435f43eba9655/client/www/public/img/peeps/nacho.jpg
--------------------------------------------------------------------------------
/client/www/public/img/peeps/sean.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/instantdb/instant/fd03a3aa4a0074e6d4a61eb522d435f43eba9655/client/www/public/img/peeps/sean.png
--------------------------------------------------------------------------------
/client/www/public/img/yc_logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/instantdb/instant/fd03a3aa4a0074e6d4a61eb522d435f43eba9655/client/www/public/img/yc_logo.png
--------------------------------------------------------------------------------
/client/www/public/marketing/discord-icon.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/client/www/public/marketing/github-icon.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/client/www/public/posts/pg_upgrade/blue_green.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/instantdb/instant/fd03a3aa4a0074e6d4a61eb522d435f43eba9655/client/www/public/posts/pg_upgrade/blue_green.png
--------------------------------------------------------------------------------
/client/www/public/posts/pg_upgrade/clone_upgrade_replicate.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/instantdb/instant/fd03a3aa4a0074e6d4a61eb522d435f43eba9655/client/www/public/posts/pg_upgrade/clone_upgrade_replicate.png
--------------------------------------------------------------------------------
/client/www/public/posts/pg_upgrade/create_replicate.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/instantdb/instant/fd03a3aa4a0074e6d4a61eb522d435f43eba9655/client/www/public/posts/pg_upgrade/create_replicate.png
--------------------------------------------------------------------------------
/client/www/public/posts/pg_upgrade/going_manual.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/instantdb/instant/fd03a3aa4a0074e6d4a61eb522d435f43eba9655/client/www/public/posts/pg_upgrade/going_manual.png
--------------------------------------------------------------------------------
/client/www/public/posts/pg_upgrade/in_place.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/instantdb/instant/fd03a3aa4a0074e6d4a61eb522d435f43eba9655/client/www/public/posts/pg_upgrade/in_place.png
--------------------------------------------------------------------------------
/client/www/public/posts/pg_upgrade/no_downtime.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/instantdb/instant/fd03a3aa4a0074e6d4a61eb522d435f43eba9655/client/www/public/posts/pg_upgrade/no_downtime.png
--------------------------------------------------------------------------------
/client/www/public/posts/pg_upgrade/switch_subs.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/instantdb/instant/fd03a3aa4a0074e6d4a61eb522d435f43eba9655/client/www/public/posts/pg_upgrade/switch_subs.png
--------------------------------------------------------------------------------
/client/www/public/posts/pg_upgrade/switch_writes.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/instantdb/instant/fd03a3aa4a0074e6d4a61eb522d435f43eba9655/client/www/public/posts/pg_upgrade/switch_writes.png
--------------------------------------------------------------------------------
/client/www/public/posts/pg_upgrade/the_system.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/instantdb/instant/fd03a3aa4a0074e6d4a61eb522d435f43eba9655/client/www/public/posts/pg_upgrade/the_system.png
--------------------------------------------------------------------------------
/client/www/styles/docs/tailwind.css:
--------------------------------------------------------------------------------
1 | @import 'tailwindcss/base';
2 | @import './prism.css';
3 | @import 'tailwindcss/components';
4 | @import 'tailwindcss/utilities';
5 |
6 | .bg-prism {
7 | background-color: #fff;
8 | }
9 |
10 | .bg-prism-dark {
11 | background-color: #eee8e0;
12 | }
13 |
--------------------------------------------------------------------------------
/client/www/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 | "baseUrl": ".",
18 | "paths": {
19 | "@/components/*": ["components/*"],
20 | "@/markdoc/*": ["markdoc/*"],
21 | "@/pages/*": ["pages/*"],
22 | "@/lib/*": ["lib/*"],
23 | "@/data/*": ["data/*"],
24 | "@/utils/*": ["utils/*"]
25 | }
26 | },
27 | "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx"],
28 | "exclude": ["node_modules"]
29 | }
30 |
--------------------------------------------------------------------------------
/server/.clj-kondo/.gitignore:
--------------------------------------------------------------------------------
1 | .cache
2 |
--------------------------------------------------------------------------------
/server/.clj-kondo/ci-config.edn:
--------------------------------------------------------------------------------
1 | {:output {:pattern "::{{level}} file=server/{{filename}},line={{row}},col={{col}}::{{message}}\n{{filename}}:{{row}}:{{col}}: {{level}}: {{message}}"}}
2 |
--------------------------------------------------------------------------------
/server/.clj-kondo/config.edn:
--------------------------------------------------------------------------------
1 | {:linters {:unresolved-namespace {:exclude [tool]}
2 | :clojure-lsp/unused-public-var {:level :off}
3 | :unresolved-var {:exclude [ring.util.http-response/set-cookie
4 | amazonica.aws.s3]}}
5 | :ignore [:inline-def]
6 | :hooks {:analyze-call {instant.jdbc.sql/defsql hooks.defsql/defsql
7 | tool/with-prod-conn hooks.with-prod-conn/with-prod-conn
8 | instant.fixtures/with-indexing-job-queue hooks.with-indexing-job-queue/with-indexing-job-queue}}
9 | :lint-as {instant.jdbc.sql/with-connection clojure.core/let
10 | instant.util.tracer/with-exceptions-silencer clojure.core/fn
11 | clojure.core.cache/defcache clojure.core/defrecord}}
12 |
--------------------------------------------------------------------------------
/server/.clj-kondo/hooks/with_indexing_job_queue.clj:
--------------------------------------------------------------------------------
1 | (ns hooks.with-indexing-job-queue
2 | (:require [clj-kondo.hooks-api :as api]))
3 |
4 | (defn with-indexing-job-queue
5 | [{:keys [node]}]
6 | (let [[binding-var & body] (rest (:children node))
7 | job-queue-sym-node binding-var
8 | new-node
9 | (api/list-node
10 | (list*
11 | (api/token-node 'clojure.core/let)
12 | (api/vector-node
13 | [job-queue-sym-node
14 | (api/token-node :dummy-v)])
15 | body))]
16 | {:node new-node}))
17 |
--------------------------------------------------------------------------------
/server/.clj-kondo/hooks/with_prod_conn.clj:
--------------------------------------------------------------------------------
1 | (ns hooks.with-prod-conn
2 | (:require [clj-kondo.hooks-api :as api]))
3 |
4 | (defn with-prod-conn
5 | [{:keys [node]}]
6 | (let [[binding-vec & body] (rest (:children node))
7 | conn-sym-node (first (:children binding-vec))
8 | new-node
9 | (api/list-node
10 | (list*
11 | (api/token-node 'clojure.core/let)
12 | (api/vector-node
13 | [conn-sym-node
14 | (api/token-node :dummy-v)])
15 | body))]
16 | {:node new-node}))
17 |
--------------------------------------------------------------------------------
/server/.clj-kondo/imports/babashka/sci/config.edn:
--------------------------------------------------------------------------------
1 | {:hooks {:macroexpand {sci.core/copy-ns sci.core/copy-ns}}}
2 |
--------------------------------------------------------------------------------
/server/.clj-kondo/imports/babashka/sci/sci/core.clj:
--------------------------------------------------------------------------------
1 | (ns sci.core)
2 |
3 | (defmacro copy-ns
4 | ([ns-sym sci-ns]
5 | `(copy-ns ~ns-sym ~sci-ns nil))
6 | ([ns-sym sci-ns opts]
7 | `[(quote ~ns-sym)
8 | ~sci-ns
9 | (quote ~opts)]))
10 |
--------------------------------------------------------------------------------
/server/.clj-kondo/imports/com.github.seancorfield/next.jdbc/config.edn:
--------------------------------------------------------------------------------
1 | {:hooks
2 | {:analyze-call
3 | {next.jdbc/with-transaction
4 | hooks.com.github.seancorfield.next-jdbc/with-transaction
5 | next.jdbc/with-transaction+options
6 | hooks.com.github.seancorfield.next-jdbc/with-transaction+options}}
7 | :lint-as {next.jdbc/on-connection clojure.core/with-open
8 | next.jdbc/on-connection+options clojure.core/with-open}}
9 |
--------------------------------------------------------------------------------
/server/.clj-kondo/imports/com.github.steffan-westcott/clj-otel-api/config.edn:
--------------------------------------------------------------------------------
1 | ;!zprint {:width 140}
2 |
3 | {:lint-as {steffan-westcott.clj-otel.api.trace.span/with-span-binding clojure.core/let}}
--------------------------------------------------------------------------------
/server/.clj-kondo/imports/hiccup/hiccup/config.edn:
--------------------------------------------------------------------------------
1 | {:lint-as {hiccup.def/defhtml clojure.core/defn}
2 | :hooks {:analyze-call {hiccup.def/defelem hiccup.hooks/defelem}}}
3 |
--------------------------------------------------------------------------------
/server/.clj-kondo/imports/http-kit/http-kit/config.edn:
--------------------------------------------------------------------------------
1 |
2 | {:hooks
3 | {:analyze-call {org.httpkit.server/with-channel httpkit.with-channel/with-channel}}}
4 |
--------------------------------------------------------------------------------
/server/.clj-kondo/imports/http-kit/http-kit/httpkit/with_channel.clj:
--------------------------------------------------------------------------------
1 | (ns httpkit.with-channel
2 | (:require [clj-kondo.hooks-api :as api]))
3 |
4 | (defn with-channel [{node :node}]
5 | (let [[request channel & body] (rest (:children node))]
6 | (when-not (and request channel) (throw (ex-info "No request or channel provided" {})))
7 | (when-not (api/token-node? channel) (throw (ex-info "Missing channel argument" {})))
8 | (let [new-node
9 | (api/list-node
10 | (list*
11 | (api/token-node 'let)
12 | (api/vector-node [channel (api/vector-node [])])
13 | request
14 | body))]
15 |
16 | {:node new-node})))
17 |
--------------------------------------------------------------------------------
/server/.clj-kondo/imports/instaparse/config.edn:
--------------------------------------------------------------------------------
1 | {:lint-as {instaparse.macros/defclone clojure.core/def
2 | instaparse.macros/set-global-var! clojure.core/set!}}
3 |
--------------------------------------------------------------------------------
/server/.clj-kondo/imports/io.github.tonsky/clojure-plus/config.edn:
--------------------------------------------------------------------------------
1 | {:hooks
2 | {:analyze-call
3 | {clojure+.core/if+ hooks.core/ifplus-hook
4 | clojure+.core/when+ hooks.core/whenplus-hook
5 | clojure+.core/cond+ hooks.core/condplus-hook}}}
--------------------------------------------------------------------------------
/server/.clj-kondo/imports/rewrite-clj/rewrite-clj/config.edn:
--------------------------------------------------------------------------------
1 | {:lint-as
2 | {rewrite-clj.zip/subedit-> clojure.core/->
3 | rewrite-clj.zip/subedit->> clojure.core/->>
4 | rewrite-clj.zip/edit-> clojure.core/->
5 | rewrite-clj.zip/edit->> clojure.core/->>}}
6 |
--------------------------------------------------------------------------------
/server/.clj-kondo/imports/taoensso/encore/config.edn:
--------------------------------------------------------------------------------
1 | {:hooks
2 | {:analyze-call
3 | {taoensso.encore/defalias taoensso.encore/defalias
4 | taoensso.encore/defn-cached taoensso.encore/defn-cached}}}
5 |
--------------------------------------------------------------------------------
/server/.ebextensions/resources.config:
--------------------------------------------------------------------------------
1 | Resources:
2 | AWSEBAutoScalingGroup:
3 | Type: AWS::AutoScaling::AutoScalingGroup
4 | Properties:
5 | #PlacementGroup: "Instant-docker-prod-placement-group"
6 |
--------------------------------------------------------------------------------
/server/.ebextensions/sysctl.config:
--------------------------------------------------------------------------------
1 | files:
2 | "/etc/sysctl.d/99-instant.conf":
3 | mode: "000644"
4 | owner: root
5 | group: root
6 | content: |
7 | kernel.perf_event_paranoid = 1
8 | kernel.kptr_restrict = 0
9 |
10 | commands:
11 | 01_reload_sysctl:
12 | command: |
13 | sysctl -w kernel.perf_event_paranoid=1
14 | sysctl -w kernel.kptr_restrict=0
15 |
--------------------------------------------------------------------------------
/server/.elasticbeanstalk/config.yml:
--------------------------------------------------------------------------------
1 | branch-defaults:
2 | default:
3 | environment: instant-docker-prod-env
4 | group_suffix: null
5 | global:
6 | application_name: instant-docker-prod
7 | branch: null
8 | default_ec2_keyname: aws-eb
9 | default_platform: Docker
10 | default_region: us-east-1
11 | include_git_submodules: true
12 | instance_profile: null
13 | platform_name: null
14 | platform_version: null
15 | profile: null
16 | repository: null
17 | sc: null
18 | workspace_type: Application
19 |
--------------------------------------------------------------------------------
/server/.gitignore:
--------------------------------------------------------------------------------
1 | /target
2 | /classes
3 | /checkouts
4 | profiles.clj
5 | pom.xml
6 | pom.xml.asc
7 | *.jar
8 | *.class
9 | /.lein-*
10 | /.nrepl-port
11 | /.prepl-port
12 | .hgignore
13 | .hg/
14 | .DS_Store
15 | node_modules
16 | .lsp
17 | .elasticbeanstealk/app_versions
18 | .idea
19 | server.iml
20 | .babashka-pod-*
21 | dev-resources/honeycomb-export*
22 | dev-resources/certs
23 | resources/metrics
24 |
--------------------------------------------------------------------------------
/server/.platform/hooks/prebuild/prebuild.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | set -x
4 |
5 | file="/etc/deploy_count.txt"
6 |
7 | touch "$file"
8 | if [ ! -f "$file" ]; then
9 | echo "0" > "$file"
10 | fi
11 |
12 | read -r current_count < "$file"
13 | new_count=$((current_count + 1))
14 | echo "$new_count" > "$file"
15 |
16 | hz_port=$((5701 + (new_count % 8)))
17 |
18 | echo "HZ_PORT=$hz_port" > hazelcast.env
19 |
--------------------------------------------------------------------------------
/server/Dockerfile-dev:
--------------------------------------------------------------------------------
1 | FROM amazoncorretto:22
2 |
3 | WORKDIR /app
4 |
5 | RUN yum -y install tar gzip git make
6 |
7 | RUN curl -L -O https://github.com/clojure/brew-install/releases/download/1.11.3.1463/linux-install.sh
8 |
9 | RUN chmod +x linux-install.sh
10 | RUN ./linux-install.sh
11 |
12 | RUN mkdir gomigrate && cd gomigrate && \
13 | ARCH=$(uname -m) && \
14 | if [ "$ARCH" = "x86_64" ]; then \
15 | ARCH="amd64"; \
16 | elif [ "$ARCH" = "aarch64" ]; then \
17 | ARCH="arm64"; \
18 | else \
19 | echo "Unsupported architecture: $ARCH"; exit 1; \
20 | fi && \
21 | curl -vvv -L "https://github.com/golang-migrate/migrate/releases/download/v4.17.0/migrate.linux-$ARCH.tar.gz" | tar xvz && \
22 | mv migrate /usr/local/bin && \
23 | cd .. && rm -r gomigrate
24 |
25 | COPY deps.edn .
26 |
27 | RUN clojure -P -M:dev
28 | RUN clojure -P -M:oss-bootstrap
29 |
30 | EXPOSE 8888
31 | EXPOSE 6005
32 |
33 | CMD ["make", "dev-oss"]
34 |
--------------------------------------------------------------------------------
/server/ci_trigger.txt:
--------------------------------------------------------------------------------
1 | 1
2 |
--------------------------------------------------------------------------------
/server/dev-postgres/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM postgres:16
2 |
3 | RUN apt-get update && \
4 | apt-get install -y \
5 | build-essential \
6 | postgresql-server-dev-16 \
7 | postgresql-16-pg-hint-plan \
8 | wget && \
9 | mkdir build && cd build && \
10 | wget https://github.com/eulerto/wal2json/archive/refs/tags/wal2json_2_6.tar.gz && \
11 | tar -zxf wal2json_2_6.tar.gz && \
12 | cd wal2json-wal2json_2_6 && \
13 | make && \
14 | make install && \
15 | cd ../.. && \
16 | rm -rf build && \
17 | apt-get remove -y \
18 | build-essential \
19 | postgresql-server-dev-16 \
20 | wget && \
21 | apt-get autoremove -y && \
22 | apt-get clean
23 |
24 | CMD ["postgres", \
25 | "-c", "wal_level=logical", \
26 | "-c", "max_replication_slots=4", \
27 | "-c", "max_wal_senders=4", \
28 | "-c", "shared_preload_libraries=pg_hint_plan", \
29 | "-c", "random_page_cost=1.1"]
30 |
--------------------------------------------------------------------------------
/server/dev-postgres/Makefile:
--------------------------------------------------------------------------------
1 | MAKEFLAGS = --no-print-directory --always-make --silent
2 | MAKE = make $(MAKEFLAGS)
3 |
4 | ecr-login:
5 | aws ecr-public get-login-password --region us-east-1 | docker login --username AWS --password-stdin public.ecr.aws
6 |
7 | build-and-push-image:
8 | docker buildx build --platform linux/amd64,linux/arm64 --push \
9 | -t public.ecr.aws/z9j8u5b3/instant-public:postgresql-16-pg-hint-plan .
10 |
--------------------------------------------------------------------------------
/server/dev-postgres/README.md:
--------------------------------------------------------------------------------
1 | Builds the image for postgres that is used in the local docker compose setup.
2 |
3 | Log in to the instant public ecr registry:
4 |
5 | ```sh
6 | make ecr-login
7 | ```
8 |
9 | Build and push the image:
10 |
11 | ```sh
12 | make build-and-push-image
13 | ```
14 |
--------------------------------------------------------------------------------
/server/dev-resources/hooks/pre-commit:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | # A pre-commit hook to run clj-kondo against changed files
4 |
5 | if git rev-parse --verify HEAD >/dev/null 2>&1
6 | then
7 | against=HEAD
8 | else
9 | # Initial commit: diff against an empty tree object
10 | against=$(git hash-object -t tree /dev/null)
11 | fi
12 |
13 | CHANGED=$(git diff --cached --name-only --diff-filter=AM $against | grep -E '^server/(src|test)/.*\.clj[cs]?$' | sed 's/^server\///')
14 | cd server
15 |
16 | if !(clj-kondo --lint $CHANGED)
17 | then
18 | echo
19 | echo "Error: new clj-kondo errors found. Please fix them, make sure 'make lint' runs without warnings and then commit."
20 | exit 1
21 | fi
22 |
23 | exec git diff-index --check --cached $against --
--------------------------------------------------------------------------------
/server/dev/data_readers.clj:
--------------------------------------------------------------------------------
1 | {p tool/p}
--------------------------------------------------------------------------------
/server/dev/user.clj:
--------------------------------------------------------------------------------
1 | (ns user
2 | (:require
3 | [clj-reload.core :as reload]
4 | [clojure+.error]
5 | [clojure+.hashp]
6 | [clojure+.print]
7 | [clojure+.test]
8 | [tool]))
9 |
10 | (.doReset #'*warn-on-reflection* true)
11 |
12 | (clojure+.error/install!)
13 | (clojure+.hashp/install!)
14 | (clojure+.print/install!)
15 | (clojure+.test/install!)
16 |
17 | (reload/init
18 | {:dirs ["src" "dev" "test"]
19 | :no-reload '[user]
20 | :output :quieter})
21 |
22 | (def reload
23 | reload/reload)
24 |
25 | (defn test-all []
26 | (reload/reload {:only #"instant\..*-test"})
27 | (clojure+.test/run))
28 |
--------------------------------------------------------------------------------
/server/flags-config/.env:
--------------------------------------------------------------------------------
1 | INSTANT_APP_ID=24a4d71b-7bb2-4630-9aee-01146af26239
2 |
--------------------------------------------------------------------------------
/server/flags-config/README.md:
--------------------------------------------------------------------------------
1 | Stores the perms and schema info for the flags in the instant-config app.
2 |
3 | Install deps:
4 | ```
5 | pnpm i
6 | ```
7 |
8 | login:
9 | ```
10 | pnpm run login
11 | ```
12 |
13 | or in dev:
14 | ```
15 | pnpm run dev:login
16 | ```
17 |
18 | pull schema and perms:
19 | ```
20 | pnpm run pull
21 | ```
22 |
23 | or in dev:
24 | ```
25 | pnpm run dev:pull
26 | ```
27 |
28 | push schema and perms:
29 | ```
30 | pnpm run push
31 | ```
32 |
33 | or in dev:
34 | ```
35 | pnpm run dev:push
36 | ```
37 |
--------------------------------------------------------------------------------
/server/flags-config/instant.perms.ts:
--------------------------------------------------------------------------------
1 | // Docs: https://www.instantdb.com/docs/permissions
2 |
3 | import type { InstantRules } from "@instantdb/core";
4 |
5 | const rules = {
6 | attrs: {
7 | allow: {
8 | create: "false",
9 | },
10 | },
11 | $default: {
12 | allow: {
13 | $default: "false",
14 | },
15 | },
16 | } satisfies InstantRules;
17 |
18 | export default rules;
19 |
--------------------------------------------------------------------------------
/server/flags-config/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "flags-config",
3 | "version": "1.0.0",
4 | "scripts": {
5 | "login": "instant-cli login",
6 | "pull": "instant-cli pull",
7 | "push": "instant-cli push",
8 | "dev:login": "INSTANT_CLI_DEV=1 instant-cli login",
9 | "dev:pull": "INSTANT_CLI_DEV=1 instant-cli pull",
10 | "dev:push": "INSTANT_CLI_DEV=1 instant-cli push"
11 | },
12 | "dependencies": {
13 | "@instantdb/core": "^0.19.1",
14 | "instant-cli": "^0.19.1"
15 | },
16 | "packageManager": "pnpm@10.2.0"
17 | }
18 |
--------------------------------------------------------------------------------
/server/refinery/config-redis.yaml:
--------------------------------------------------------------------------------
1 | ## This is the main config file. There is a fallback file at ./config.yaml
2 | ## in case we need to disable redis. Just remove the REFINERY_REDIS_HOST
3 | ## env var from the eb config to switch to the fallback config.
4 | General:
5 | ConfigurationVersion: 2
6 | Network:
7 | ListenAddr: "0.0.0.0:8080"
8 | PeerListenAddr: "0.0.0.0:8081"
9 | GRPCServerParameters:
10 | Enabled: true
11 | ListenAddr: "0.0.0.0:8082"
12 | RefineryTelemetry:
13 | AddRuleReasonToTrace: true
14 | OTelMetrics:
15 | Enabled: true
16 | PeerManagement:
17 | Type: redis
18 | RedisPeerManagement:
19 | UseTLS: true
20 | Logger:
21 | Level: warn
22 | Debugging:
23 | # Set to true to see which events would have been filtered
24 | DryRun: false
25 |
--------------------------------------------------------------------------------
/server/refinery/config.yaml:
--------------------------------------------------------------------------------
1 | ## This is a fallback file in case we need to disable redis for refinery
2 | ## The main config file is ./config-redis.yaml
3 | General:
4 | ConfigurationVersion: 2
5 | Network:
6 | ListenAddr: "0.0.0.0:8080"
7 | PeerListenAddr: "0.0.0.0:8081"
8 | GRPCServerParameters:
9 | Enabled: true
10 | ListenAddr: "0.0.0.0:8082"
11 | RefineryTelemetry:
12 | AddRuleReasonToTrace: true
13 | OTelMetrics:
14 | Enabled: true
15 | PeerManagement:
16 | Peers: []
17 | RedisPeerManagement:
18 | UseTLS: true
19 | Logger:
20 | Level: warn
21 | Debugging:
22 | # Set to true to see which events would have been filtered
23 | DryRun: false
24 |
--------------------------------------------------------------------------------
/server/refinery/docker-compose.yml:
--------------------------------------------------------------------------------
1 | services:
2 | refinery:
3 | image: honeycombio/refinery:2.8.4
4 | volumes:
5 | - ./config.yaml:/etc/refinery/refinery.yaml
6 | - ./config-redis.yaml:/etc/refinery/refinery-redis.yaml
7 | - ./rules.yaml:/etc/refinery/rules.yaml
8 | environment:
9 | - REFINERY_HONEYCOMB_API_KEY=${REFINERY_HONEYCOMB_API_KEY}
10 | - REFINERY_REDIS_HOST=${REFINERY_REDIS_HOST}
11 | env_file:
12 | - ./refinery.env
13 | network_mode: "host"
14 | restart: on-failure
15 | stop_grace_period: 30s
16 |
--------------------------------------------------------------------------------
/server/refinery/refinery.env:
--------------------------------------------------------------------------------
1 | # Set REFINERY_CONFIG to the redis version if we've set the redis
2 | # host, and the file version if we haven't. Allows us to easily
3 | # disable redis by removing the REFINERY_REDIS_HOST env var
4 |
5 | REFINERY_CONFIG=${REFINERY_REDIS_HOST:+/etc/refinery/refinery-redis.yaml}
6 | REFINERY_CONFIG=${REFINERY_CONFIG:-/etc/refinery/refinery.yaml}
7 |
--------------------------------------------------------------------------------
/server/refinery/rules.yaml:
--------------------------------------------------------------------------------
1 | RulesVersion: 2
2 | Samplers:
3 | __default__:
4 | DeterministicSampler:
5 | SampleRate: 1
6 | prod:
7 | RulesBasedSampler:
8 | Rules:
9 | - Name: keep errors
10 | SampleRate: 1
11 | Conditions:
12 | - Field: error
13 | Operator: exists
14 |
15 | - Name: default rule
16 | Sampler:
17 | EMAThroughputSampler:
18 | GoalThroughputPerSec: 25
19 | UseClusterSize: true
20 | FieldList:
21 | - root.name
22 | - root.op
23 | - root.entropy
24 |
--------------------------------------------------------------------------------
/server/resources/config/test.edn:
--------------------------------------------------------------------------------
1 | {:aead-keyset {:encrypted? false
2 | :json "{\"primaryKeyId\":1165732053,\"key\":[{\"keyData\":{\"typeUrl\":\"type.googleapis.com/google.crypto.tink.AesGcmKey\",\"value\":\"GhBhFBF+w6HyDFJxNF0R50Pt\",\"keyMaterialType\":\"SYMMETRIC\"},\"status\":\"ENABLED\",\"keyId\":1165732053,\"outputPrefixType\":\"TINK\"}]}"}}
3 |
--------------------------------------------------------------------------------
/server/resources/logback.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | %msg%n
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/server/resources/migrations/01_bootstrap.down.sql:
--------------------------------------------------------------------------------
1 | DROP TABLE instant_user_outreaches;
2 | DROP TABLE instant_user_refresh_tokens;
3 | DROP TABLE instant_user_magic_codes;
4 | DROP TABLE app_user_refresh_tokens;
5 | DROP TABLE app_user_magic_codes;
6 | DROP TABLE app_users;
7 | DROP TABLE triples;
8 | DROP TABLE attrs;
9 | DROP TABLE idents;
10 | DROP TABLE deprecated_triples;
11 | DROP TABLE deprecated_transaction_counters;
12 | DROP TABLE apps;
13 | DROP TABLE instant_users;
14 |
--------------------------------------------------------------------------------
/server/resources/migrations/02_add_grabs.down.sql:
--------------------------------------------------------------------------------
1 | DROP TABLE grabs;
2 |
--------------------------------------------------------------------------------
/server/resources/migrations/02_add_grabs.up.sql:
--------------------------------------------------------------------------------
1 | CREATE TABLE grabs (
2 | id text PRIMARY KEY,
3 | created_at timestamp DEFAULT NOW()
4 | );
5 |
6 |
--------------------------------------------------------------------------------
/server/resources/migrations/03_add_transactions.down.sql:
--------------------------------------------------------------------------------
1 | DROP TABLE transactions;
2 |
--------------------------------------------------------------------------------
/server/resources/migrations/03_add_transactions.up.sql:
--------------------------------------------------------------------------------
1 | CREATE TABLE transactions (
2 | id BIGINT primary key GENERATED ALWAYS AS IDENTITY,
3 | app_id uuid NOT NULL REFERENCES apps(id) ON DELETE CASCADE,
4 | created_at TIMESTAMP NOT NULL DEFAULT NOW()
5 | );
6 |
--------------------------------------------------------------------------------
/server/resources/migrations/04_add_rules.down.sql:
--------------------------------------------------------------------------------
1 | DROP TABLE rules;
2 |
--------------------------------------------------------------------------------
/server/resources/migrations/04_add_rules.up.sql:
--------------------------------------------------------------------------------
1 | CREATE TABLE rules (
2 | app_id uuid PRIMARY KEY REFERENCES apps(id) ON DELETE CASCADE,
3 | code jsonb NOT NULL
4 | );
5 | CREATE INDEX rules_app_id ON rules (app_id);
6 |
--------------------------------------------------------------------------------
/server/resources/migrations/05_add_app_admin_tokens.down.sql:
--------------------------------------------------------------------------------
1 | DROP TABLE app_admin_tokens;
2 |
--------------------------------------------------------------------------------
/server/resources/migrations/05_add_app_admin_tokens.up.sql:
--------------------------------------------------------------------------------
1 | CREATE TABLE app_admin_tokens(
2 | token uuid primary key,
3 | app_id uuid NOT NULL UNIQUE,
4 | created_at TIMESTAMP NOT NULL DEFAULT NOW(),
5 | CONSTRAINT fk_app_id
6 | FOREIGN KEY(app_id)
7 | REFERENCES apps(id)
8 | ON DELETE CASCADE
9 | );
10 |
--------------------------------------------------------------------------------
/server/resources/migrations/06_fix_ref_constraint_on_triples.down.sql:
--------------------------------------------------------------------------------
1 | ALTER TABLE triples DROP CONSTRAINT ref_values_are_uuid;
2 | ALTER TABLE triples
3 | ADD CONSTRAINT ref_values_are_uuid
4 | CHECK (
5 | CASE WHEN eav OR vae THEN
6 | (value->>0)::uuid IS NOT NULL
7 | ELSE TRUE
8 | END
9 | );
10 |
11 |
--------------------------------------------------------------------------------
/server/resources/migrations/06_fix_ref_constraint_on_triples.up.sql:
--------------------------------------------------------------------------------
1 | ALTER TABLE triples DROP CONSTRAINT ref_values_are_uuid;
2 | ALTER TABLE triples
3 | ADD CONSTRAINT ref_values_are_uuid
4 | CHECK (
5 | CASE WHEN eav OR vae THEN
6 | jsonb_typeof(value) = 'string' AND
7 | (value->>0)::uuid IS NOT NULL
8 | ELSE TRUE
9 | END
10 | );
11 |
12 |
--------------------------------------------------------------------------------
/server/resources/migrations/07_add_profiles.down.sql:
--------------------------------------------------------------------------------
1 | DROP TABLE instant_profiles;
2 |
--------------------------------------------------------------------------------
/server/resources/migrations/07_add_profiles.up.sql:
--------------------------------------------------------------------------------
1 | CREATE TABLE instant_profiles (
2 | id uuid PRIMARY KEY REFERENCES instant_users(id) ON DELETE CASCADE,
3 | meta jsonb NOT NULL,
4 | created_at TIMESTAMP NOT NULL DEFAULT NOW()
5 | );
6 |
--------------------------------------------------------------------------------
/server/resources/migrations/08_add_createdAt_for_triples.down.sql:
--------------------------------------------------------------------------------
1 | ALTER TABLE triples
2 | DROP COLUMN created_at;
3 |
4 | DROP FUNCTION current_unix_timestamp_ms();
5 |
--------------------------------------------------------------------------------
/server/resources/migrations/08_add_createdAt_for_triples.up.sql:
--------------------------------------------------------------------------------
1 | CREATE OR REPLACE FUNCTION current_unix_timestamp_ms()
2 | RETURNS bigint AS $$
3 | BEGIN
4 | RETURN (EXTRACT(EPOCH FROM NOW() AT TIME ZONE 'UTC') * 1000)::BIGINT;
5 | END;
6 | $$ LANGUAGE plpgsql VOLATILE;
7 |
8 | ALTER TABLE triples
9 | ADD COLUMN created_at bigint DEFAULT current_unix_timestamp_ms();
10 |
--------------------------------------------------------------------------------
/server/resources/migrations/09_add_oauth_login.down.sql:
--------------------------------------------------------------------------------
1 | alter table instant_users drop column google_sub;
2 |
3 | drop table instant_oauth_redirects;
4 |
5 | drop table instant_oauth_codes;
6 |
--------------------------------------------------------------------------------
/server/resources/migrations/09_add_oauth_login.up.sql:
--------------------------------------------------------------------------------
1 | alter table instant_users add column google_sub text unique;
2 |
3 | create table instant_oauth_redirects (
4 | -- sha256 of the state to prevent timing attacks
5 | lookup_key bytea primary key,
6 | state uuid not null,
7 | cookie uuid not null,
8 | service text not null,
9 | redirect_path text not null,
10 | created_at timestamp with time zone not null default now()
11 | );
12 |
13 | create table instant_oauth_codes (
14 | -- sha256 of the code to prevent timing attacks
15 | lookup_key bytea primary key,
16 | redirect_path text not null,
17 | user_id uuid not null references instant_users(id) on delete cascade,
18 | created_at timestamp with time zone not null default now()
19 | );
20 |
21 | -- Index so we don't have to do a full scan when a user is deleted
22 | create index on instant_oauth_codes (user_id);
23 |
--------------------------------------------------------------------------------
/server/resources/migrations/10_add_app_oauth_login.down.sql:
--------------------------------------------------------------------------------
1 | drop table app_oauth_service_providers;
2 |
3 | drop table app_oauth_clients;
4 |
5 | drop table app_oauth_redirects;
6 |
7 | drop table app_oauth_codes;
8 |
9 | drop table app_user_oauth_links;
10 |
11 | drop table app_authorized_redirect_origins;
12 |
--------------------------------------------------------------------------------
/server/resources/migrations/11_add_created_at_fields.down.sql:
--------------------------------------------------------------------------------
1 | alter table app_oauth_service_providers drop column created_at;
2 | alter table app_oauth_clients drop column created_at;
3 | alter table app_user_oauth_links drop column created_at;
4 | alter table app_authorized_redirect_origins drop column created_at;
5 |
--------------------------------------------------------------------------------
/server/resources/migrations/11_add_created_at_fields.up.sql:
--------------------------------------------------------------------------------
1 | alter table app_oauth_service_providers add column created_at timestamp with time zone not null default now();
2 | alter table app_oauth_clients add column created_at timestamp with time zone not null default now();
3 | alter table app_user_oauth_links add column created_at timestamp with time zone not null default now();
4 | alter table app_authorized_redirect_origins add column created_at timestamp with time zone not null default now();
5 |
--------------------------------------------------------------------------------
/server/resources/migrations/12_add_redirect_to_dev.down.sql:
--------------------------------------------------------------------------------
1 | alter table instant_oauth_redirects drop column redirect_to_dev;
2 |
--------------------------------------------------------------------------------
/server/resources/migrations/12_add_redirect_to_dev.up.sql:
--------------------------------------------------------------------------------
1 | alter table instant_oauth_redirects add column redirect_to_dev boolean;
2 |
--------------------------------------------------------------------------------
/server/resources/migrations/13_add_discovery_endpoint.down.sql:
--------------------------------------------------------------------------------
1 | alter table app_oauth_clients drop column discovery_endpoint;
2 |
--------------------------------------------------------------------------------
/server/resources/migrations/13_add_discovery_endpoint.up.sql:
--------------------------------------------------------------------------------
1 | alter table app_oauth_clients add column discovery_endpoint text;
2 |
--------------------------------------------------------------------------------
/server/resources/migrations/14_add_apps_created_at_index.down.sql:
--------------------------------------------------------------------------------
1 | DROP INDEX apps_created_at;
2 |
--------------------------------------------------------------------------------
/server/resources/migrations/14_add_apps_created_at_index.up.sql:
--------------------------------------------------------------------------------
1 | CREATE INDEX apps_created_at ON apps (created_at);
2 |
--------------------------------------------------------------------------------
/server/resources/migrations/15_pkce.down.sql:
--------------------------------------------------------------------------------
1 | alter table app_oauth_redirects drop column code_challenge_method;
2 | alter table app_oauth_redirects drop column code_challenge;
3 |
4 | alter table app_oauth_codes drop column code_challenge_method;
5 | alter table app_oauth_codes drop column code_challenge;
6 |
--------------------------------------------------------------------------------
/server/resources/migrations/15_pkce.up.sql:
--------------------------------------------------------------------------------
1 | alter table app_oauth_redirects add column code_challenge_method text;
2 | alter table app_oauth_redirects add column code_challenge text;
3 |
4 | alter table app_oauth_codes add column code_challenge_method text;
5 | alter table app_oauth_codes add column code_challenge text;
6 |
--------------------------------------------------------------------------------
/server/resources/migrations/16_add_stripe.down.sql:
--------------------------------------------------------------------------------
1 | drop table instant_subscriptions;
2 | drop table instant_subscription_types;
3 | drop table instant_stripe_customers;
4 |
--------------------------------------------------------------------------------
/server/resources/migrations/17_add_teams.down.sql:
--------------------------------------------------------------------------------
1 | drop table app_members;
2 | drop table app_member_invites;
3 |
--------------------------------------------------------------------------------
/server/resources/migrations/17_add_teams.up.sql:
--------------------------------------------------------------------------------
1 | create table app_members (
2 | id uuid primary key,
3 | app_id uuid not null references apps(id) on delete cascade,
4 | user_id uuid not null references instant_users(id) on delete cascade,
5 | member_role text not null,
6 | created_at timestamp with time zone not null default now(),
7 |
8 | unique (app_id, user_id)
9 | );
10 |
11 | create table app_member_invites (
12 | id uuid primary key,
13 | app_id uuid not null references apps(id) on delete cascade,
14 | inviter_id uuid not null references instant_users(id) on delete cascade,
15 | invitee_role text not null,
16 | invitee_email text not null,
17 | status text not null,
18 | created_at timestamp with time zone not null default now(),
19 |
20 | unique (app_id, invitee_email)
21 | );
22 |
--------------------------------------------------------------------------------
/server/resources/migrations/18_add_sent_at_to_invites.down.sql:
--------------------------------------------------------------------------------
1 | alter table app_member_invites drop column sent_at;
2 |
--------------------------------------------------------------------------------
/server/resources/migrations/18_add_sent_at_to_invites.up.sql:
--------------------------------------------------------------------------------
1 | alter table app_member_invites add column sent_at timestamp default now();
2 |
--------------------------------------------------------------------------------
/server/resources/migrations/19_add_app_email_templates.down.sql:
--------------------------------------------------------------------------------
1 | drop table app_email_templates;
2 | drop table app_email_senders;
--------------------------------------------------------------------------------
/server/resources/migrations/19_add_app_email_templates.up.sql:
--------------------------------------------------------------------------------
1 | create table app_email_senders (
2 | id uuid primary key,
3 | app_id uuid not null references apps(id) on delete set null,
4 | postmark_id integer not null,
5 | email text not null,
6 | name text not null,
7 |
8 | unique (email)
9 | );
10 |
11 | create table app_email_templates (
12 | id uuid primary key,
13 | app_id uuid not null references apps(id) on delete cascade,
14 | email_type text not null,
15 | sender_id uuid references app_email_senders(id) on delete set null,
16 | body text not null,
17 | subject text not null,
18 |
19 | unique (app_id, email_type)
20 | );
--------------------------------------------------------------------------------
/server/resources/migrations/20_add_name_to_app_email_templates.down.sql:
--------------------------------------------------------------------------------
1 | alter table app_email_templates drop column name;
2 |
--------------------------------------------------------------------------------
/server/resources/migrations/20_add_name_to_app_email_templates.up.sql:
--------------------------------------------------------------------------------
1 | alter table app_email_templates add column name text;
2 |
--------------------------------------------------------------------------------
/server/resources/migrations/21_change_sender_ownership_model.down.sql:
--------------------------------------------------------------------------------
1 | alter table app_email_senders
2 | drop column user_id;
--------------------------------------------------------------------------------
/server/resources/migrations/21_change_sender_ownership_model.up.sql:
--------------------------------------------------------------------------------
1 | alter table app_email_senders
2 | add column user_id uuid
3 | references instant_users(id)
4 | on delete cascade;
5 |
6 | update app_email_senders
7 | set user_id =
8 | (select creator_id from apps a where a.id = app_id);
9 |
10 | alter table app_email_senders
11 | alter column user_id
12 | set not null;
--------------------------------------------------------------------------------
/server/resources/migrations/22_drop_app_id_from_senders.down.sql:
--------------------------------------------------------------------------------
1 | alter table app_email_senders add column app_id uuid references apps(id) on delete set null
2 |
--------------------------------------------------------------------------------
/server/resources/migrations/22_drop_app_id_from_senders.up.sql:
--------------------------------------------------------------------------------
1 | alter table app_email_senders drop column app_id;
2 |
--------------------------------------------------------------------------------
/server/resources/migrations/23_jsonb_dmerge_and_raise.down.sql:
--------------------------------------------------------------------------------
1 | drop function jsonb_deep_merge(a jsonb, b jsonb);
2 | drop function jsonb_deep_merge_many(a jsonb, b jsonb);
3 | drop function raise_exception_message(a text);
--------------------------------------------------------------------------------
/server/resources/migrations/25_byop_connection_string.down.sql:
--------------------------------------------------------------------------------
1 | alter table apps drop column connection_string;
2 |
--------------------------------------------------------------------------------
/server/resources/migrations/25_byop_connection_string.up.sql:
--------------------------------------------------------------------------------
1 | alter table apps add column connection_string bytea;
2 |
--------------------------------------------------------------------------------
/server/resources/migrations/26_cli_auth.down.sql:
--------------------------------------------------------------------------------
1 | alter table instant_oauth_redirects drop column ticket;
2 | drop index instant_cli_logins_user_id_index;
3 | drop table instant_cli_logins;
4 |
--------------------------------------------------------------------------------
/server/resources/migrations/26_cli_auth.up.sql:
--------------------------------------------------------------------------------
1 | CREATE TABLE instant_cli_logins (
2 | id uuid PRIMARY KEY,
3 | secret bytea NOT NULL,
4 | used boolean NOT NULL DEFAULT false,
5 | created_at timestamp NOT NULL DEFAULT now(),
6 | user_id uuid REFERENCES instant_users(id) ON DELETE CASCADE
7 | );
8 |
9 | CREATE INDEX instant_cli_logins_user_id_index
10 | ON instant_cli_logins (user_id);
11 |
12 | ALTER TABLE instant_oauth_redirects
13 | ADD COLUMN ticket uuid
14 | REFERENCES instant_cli_logins(id) ON DELETE SET NULL;
--------------------------------------------------------------------------------
/server/resources/migrations/27_inferred_type.down.sql:
--------------------------------------------------------------------------------
1 | alter table attrs drop column inferred_types;
2 |
--------------------------------------------------------------------------------
/server/resources/migrations/27_inferred_type.up.sql:
--------------------------------------------------------------------------------
1 | alter table attrs add column inferred_types bit(32);
2 |
--------------------------------------------------------------------------------
/server/resources/migrations/28_config.down.sql:
--------------------------------------------------------------------------------
1 | drop table config;
2 |
--------------------------------------------------------------------------------
/server/resources/migrations/28_config.up.sql:
--------------------------------------------------------------------------------
1 | create table config (
2 | k text primary key not null,
3 | v json not null,
4 | created_at timestamp with time zone not null default now(),
5 | updated_at timestamp with time zone not null default now()
6 | );
7 |
8 | create or replace function update_updated_at_column()
9 | returns trigger as $$
10 | begin
11 | new.updated_at = now();
12 | return new;
13 | end;
14 | $$ language plpgsql;
15 |
16 | create trigger update_updated_at_trigger
17 | before update on config
18 | for each row
19 | execute function update_updated_at_column();
20 |
--------------------------------------------------------------------------------
/server/resources/migrations/29_clerk.down.sql:
--------------------------------------------------------------------------------
1 | alter table app_oauth_clients alter column client_id set not null;
2 | alter table app_oauth_clients alter column client_secret set not null;
3 | alter table app_oauth_clients alter column authorization_endpoint set not null;
4 | alter table app_oauth_clients alter column token_endpoint set not null;
5 | alter table app_oauth_clients drop column meta;
6 |
7 | alter table app_oauth_clients drop constraint unique_client_name_per_app;
8 |
--------------------------------------------------------------------------------
/server/resources/migrations/29_clerk.up.sql:
--------------------------------------------------------------------------------
1 | alter table app_oauth_clients alter column client_id drop not null;
2 | alter table app_oauth_clients alter column client_secret drop not null;
3 | alter table app_oauth_clients alter column authorization_endpoint drop not null;
4 | alter table app_oauth_clients alter column token_endpoint drop not null;
5 | alter table app_oauth_clients add column meta jsonb;
6 |
7 | -- Needs to be unique per app--currently only unique per provider
8 | alter table app_oauth_clients add constraint unique_client_name_per_app unique (app_id, client_name);
9 |
--------------------------------------------------------------------------------
/server/resources/migrations/30_personal_access_tokens.down.sql:
--------------------------------------------------------------------------------
1 | drop index instant_personal_access_tokens_user_id_index;
2 | drop table instant_personal_access_tokens;
3 |
--------------------------------------------------------------------------------
/server/resources/migrations/30_personal_access_tokens.up.sql:
--------------------------------------------------------------------------------
1 | create table instant_personal_access_tokens (
2 | id uuid primary key,
3 | created_at timestamp not null default now(),
4 | name text not null,
5 | user_id uuid not null references instant_users(id) on delete cascade
6 | );
7 |
8 | create index instant_personal_access_tokens_user_id_index
9 | on instant_personal_access_tokens (user_id);
10 |
--------------------------------------------------------------------------------
/server/resources/migrations/31_attrs_replica_full.down.sql:
--------------------------------------------------------------------------------
1 | alter table attrs replica identity default;
2 |
--------------------------------------------------------------------------------
/server/resources/migrations/31_attrs_replica_full.up.sql:
--------------------------------------------------------------------------------
1 | alter table attrs replica identity full;
2 |
--------------------------------------------------------------------------------
/server/resources/migrations/32_pgcrypto.down.sql:
--------------------------------------------------------------------------------
1 | -- do nothing for the down migration
2 |
--------------------------------------------------------------------------------
/server/resources/migrations/32_pgcrypto.up.sql:
--------------------------------------------------------------------------------
1 | create extension if not exists pgcrypto;
2 |
--------------------------------------------------------------------------------
/server/resources/migrations/33_users_in_triples_flag.down.sql:
--------------------------------------------------------------------------------
1 | alter table apps drop column users_in_triples;
2 |
--------------------------------------------------------------------------------
/server/resources/migrations/33_users_in_triples_flag.up.sql:
--------------------------------------------------------------------------------
1 | alter table apps add column users_in_triples boolean;
2 |
--------------------------------------------------------------------------------
/server/resources/migrations/34_hardcoded_objects.down.sql:
--------------------------------------------------------------------------------
1 | drop trigger prevent_delete_system_catalog_ident_trigger on idents;
2 | drop function prevent_delete_system_catalog_ident;
3 |
4 | drop trigger prevent_delete_system_catalog_attr_trigger on attrs;
5 | drop function prevent_delete_system_catalog_attr;
6 |
7 | drop trigger prevent_delete_system_catalog_app_trigger on apps;
8 | drop function prevent_delete_system_catalog_app;
9 |
10 | drop trigger prevent_delete_system_catalog_user_trigger on instant_users;
11 | drop function prevent_delete_system_catalog_user;
12 |
13 | delete from apps where id = 'a1111111-1111-1111-1111-111111111ca7';
14 |
15 | delete from instant_users where id = 'e1111111-1111-1111-1111-111111111ca7';
16 |
--------------------------------------------------------------------------------
/server/resources/migrations/35_cascade_delete.down.sql:
--------------------------------------------------------------------------------
1 | alter table attrs drop column on_delete;
2 |
3 | drop type attr_on_delete;
4 |
--------------------------------------------------------------------------------
/server/resources/migrations/35_cascade_delete.up.sql:
--------------------------------------------------------------------------------
1 | create type attr_on_delete as enum ('cascade');
2 |
3 | alter table attrs add column on_delete attr_on_delete;
4 |
--------------------------------------------------------------------------------
/server/resources/migrations/36_checked_data_type.down.sql:
--------------------------------------------------------------------------------
1 | drop table indexing_jobs;
2 | drop type indexing_job_status;
3 | alter table triples drop constraint valid_value_data_type;
4 |
5 | drop function triples_valid_value;
6 | drop function is_jsonb_valid_datestring;
7 | drop function is_jsonb_valid_timestamp;
8 | drop function triples_extract_date_value;
9 | drop function triples_extract_boolean_value;
10 | drop function triples_extract_number_value;
11 | drop function triples_extract_string_value;
12 |
13 |
14 | alter table triples drop column checked_data_type;
15 |
16 | alter table attrs drop column indexing;
17 | alter table attrs drop column checking_data_type;
18 | alter table attrs drop column checked_data_type;
19 |
20 | drop type checked_data_type;
21 |
--------------------------------------------------------------------------------
/server/resources/migrations/37_remove_users_in_triples_flag.down.sql:
--------------------------------------------------------------------------------
1 | alter table apps add column users_in_triples boolean;
2 |
--------------------------------------------------------------------------------
/server/resources/migrations/37_remove_users_in_triples_flag.up.sql:
--------------------------------------------------------------------------------
1 | alter table apps drop column users_in_triples;
2 |
--------------------------------------------------------------------------------
/server/resources/migrations/38_uniqueing.down.sql:
--------------------------------------------------------------------------------
1 | alter table attrs drop column setting_unique;
2 |
3 | alter table indexing_jobs drop column invalid_unique_value;
4 | alter table indexing_jobs drop column invalid_entity_id;
5 | alter table indexing_jobs drop column error_detail;
6 |
--------------------------------------------------------------------------------
/server/resources/migrations/38_uniqueing.up.sql:
--------------------------------------------------------------------------------
1 | alter table attrs add column setting_unique boolean;
2 |
3 | alter table indexing_jobs add column invalid_unique_value jsonb;
4 | alter table indexing_jobs add column invalid_entity_id uuid;
5 | alter table indexing_jobs add column error_detail text;
6 |
--------------------------------------------------------------------------------
/server/resources/migrations/39_fix_extract_boolean.down.sql:
--------------------------------------------------------------------------------
1 | -- no down migration
2 |
--------------------------------------------------------------------------------
/server/resources/migrations/39_fix_extract_boolean.up.sql:
--------------------------------------------------------------------------------
1 | -- Had the wrong return type
2 | drop function triples_extract_boolean_value;
3 |
4 | create or replace function triples_extract_boolean_value(value jsonb)
5 | returns boolean as $$
6 | begin
7 | if jsonb_typeof(value) = 'boolean' then
8 | return (value->>0)::boolean;
9 | else
10 | return null;
11 | end if;
12 | end;
13 | $$ language plpgsql immutable;
14 |
--------------------------------------------------------------------------------
/server/resources/migrations/40_checked_indexes.down.sql:
--------------------------------------------------------------------------------
1 | drop index triples_string_trgm_gist_idx;
2 |
3 | drop index triples_number_type_idx;
4 |
5 | drop index triples_boolean_type_idx;
6 |
7 | drop index triples_date_type_idx;
8 |
9 | drop extension btree_gist;
10 | drop extension pg_trgm;
11 |
--------------------------------------------------------------------------------
/server/resources/migrations/41_primary_keys.down.sql:
--------------------------------------------------------------------------------
1 | -- no down migration for adding back deprecated triples
2 |
3 | alter table instant_subscriptions drop column id;
4 |
--------------------------------------------------------------------------------
/server/resources/migrations/41_primary_keys.up.sql:
--------------------------------------------------------------------------------
1 | drop table if exists deprecated_triples;
2 |
3 | alter table instant_subscriptions add column id uuid primary key default gen_random_uuid();
4 |
--------------------------------------------------------------------------------
/server/resources/migrations/42_add_transactions_app_id_idx.down.sql:
--------------------------------------------------------------------------------
1 | DROP INDEX transactions_app_id_idx;
2 |
--------------------------------------------------------------------------------
/server/resources/migrations/42_add_transactions_app_id_idx.up.sql:
--------------------------------------------------------------------------------
1 | CREATE INDEX IF NOT EXISTS transactions_app_id_idx ON transactions (app_id);
2 |
--------------------------------------------------------------------------------
/server/resources/migrations/44_add_daily_app_transactions.down.sql:
--------------------------------------------------------------------------------
1 | DROP TABLE daily_app_transactions;
2 |
--------------------------------------------------------------------------------
/server/resources/migrations/44_add_daily_app_transactions.up.sql:
--------------------------------------------------------------------------------
1 | CREATE TABLE daily_app_transactions (
2 | date date,
3 | app_id uuid,
4 | active_date timestamp without time zone,
5 | is_active boolean,
6 | count bigint,
7 | UNIQUE (date, app_id, is_active)
8 | );
9 |
--------------------------------------------------------------------------------
/server/resources/migrations/46_add_created_at_index_to_transactions.down.sql:
--------------------------------------------------------------------------------
1 | DROP INDEX transactions_created_at_idx;
2 |
--------------------------------------------------------------------------------
/server/resources/migrations/46_add_created_at_index_to_transactions.up.sql:
--------------------------------------------------------------------------------
1 | CREATE INDEX IF NOT EXISTS transactions_created_at_idx ON transactions(created_at);
2 |
--------------------------------------------------------------------------------
/server/resources/migrations/47_add_replica_id_to_daily_metrics.down.sql:
--------------------------------------------------------------------------------
1 | -- Remove the replica identity setting
2 | ALTER TABLE daily_app_transactions REPLICA IDENTITY DEFAULT;
3 |
4 | -- Allow columns to be nullable again
5 | ALTER TABLE daily_app_transactions ALTER COLUMN is_active DROP NOT NULL;
6 | ALTER TABLE daily_app_transactions ALTER COLUMN app_id DROP NOT NULL;
7 | ALTER TABLE daily_app_transactions ALTER COLUMN date DROP NOT NULL;
8 |
--------------------------------------------------------------------------------
/server/resources/migrations/47_add_replica_id_to_daily_metrics.up.sql:
--------------------------------------------------------------------------------
1 | -- Ensure all columns in the unique index are non-nullable
2 | ALTER TABLE daily_app_transactions ALTER COLUMN date SET NOT NULL;
3 | ALTER TABLE daily_app_transactions ALTER COLUMN app_id SET NOT NULL;
4 | ALTER TABLE daily_app_transactions ALTER COLUMN is_active SET NOT NULL;
5 |
6 | -- Set the replica identity to use the unique index
7 | ALTER TABLE daily_app_transactions
8 | REPLICA IDENTITY USING INDEX daily_app_transactions_date_app_id_is_active_key;
9 |
--------------------------------------------------------------------------------
/server/resources/migrations/48_add_dap_primary_key.down.sql:
--------------------------------------------------------------------------------
1 | alter table daily_app_transactions drop column id;
2 |
--------------------------------------------------------------------------------
/server/resources/migrations/48_add_dap_primary_key.up.sql:
--------------------------------------------------------------------------------
1 | alter table daily_app_transactions add column id uuid primary key default gen_random_uuid();
2 |
--------------------------------------------------------------------------------
/server/resources/migrations/49_add_user_flags.down.sql:
--------------------------------------------------------------------------------
1 | DROP TABLE user_flags;
2 |
--------------------------------------------------------------------------------
/server/resources/migrations/49_add_user_flags.up.sql:
--------------------------------------------------------------------------------
1 | CREATE TABLE user_flags (
2 | id UUID PRIMARY KEY,
3 | user_id UUID NOT NULL REFERENCES instant_users(id) ON DELETE CASCADE,
4 | flag_name TEXT NOT NULL,
5 | created_at TIMESTAMP NOT NULL DEFAULT now(),
6 | UNIQUE (user_id, flag_name)
7 | );
8 |
--------------------------------------------------------------------------------
/server/resources/migrations/50_add_app_upload_urls.down.sql:
--------------------------------------------------------------------------------
1 | DROP TABLE app_upload_urls;
2 |
--------------------------------------------------------------------------------
/server/resources/migrations/50_add_app_upload_urls.up.sql:
--------------------------------------------------------------------------------
1 | CREATE TABLE app_upload_urls (
2 | id uuid PRIMARY KEY,
3 | app_id uuid NOT NULL REFERENCES apps(id) ON DELETE CASCADE,
4 | path text NOT NULL,
5 | created_at TIMESTAMP NOT NULL DEFAULT NOW(),
6 | expired_at TIMESTAMP NOT NULL DEFAULT NOW() + INTERVAL '5 minutes'
7 | );
8 |
9 | create index on app_upload_urls(app_id);
10 |
--------------------------------------------------------------------------------
/server/resources/migrations/51_add_triples_created_at_index.down.sql:
--------------------------------------------------------------------------------
1 | DROP INDEX triples_created_at_idx;
2 |
--------------------------------------------------------------------------------
/server/resources/migrations/51_add_triples_created_at_index.up.sql:
--------------------------------------------------------------------------------
1 | CREATE INDEX IF NOT EXISTS triples_created_at_idx
2 | ON triples(app_id, attr_id, created_at);
3 |
--------------------------------------------------------------------------------
/server/resources/migrations/52_add_app_files_to_sweep.down.sql:
--------------------------------------------------------------------------------
1 | DROP TRIGGER insert_files_to_sweep_trigger ON triples;
2 | DROP TRIGGER update_files_to_sweep_trigger ON triples;
3 |
4 | DROP FUNCTION create_file_to_sweep();
5 | DROP FUNCTION create_file_to_sweep_on_update();
6 |
7 | DROP TABLE app_files_to_sweep;
8 |
--------------------------------------------------------------------------------
/server/resources/migrations/53_change_indexing_of_triple_nulls.down.sql:
--------------------------------------------------------------------------------
1 | create unique index if not exists av_index_temp_name
2 | on triples(app_id, attr_id, value)
3 | include (entity_id)
4 | where av;
5 |
6 | drop index av_index;
7 |
8 | drop function public.json_null_to_null(v jsonb);
9 |
10 | alter index av_index_temp_name rename to av_index;
11 |
--------------------------------------------------------------------------------
/server/resources/migrations/53_change_indexing_of_triple_nulls.up.sql:
--------------------------------------------------------------------------------
1 | create or replace function public.json_null_to_null(v jsonb) returns jsonb
2 | language sql immutable
3 | as $$
4 | select case
5 | when v = 'null'::jsonb then null
6 | else v
7 | end;
8 | $$;
9 |
10 | create unique index if not exists av_ignore_nulls_index
11 | on triples(app_id, attr_id, json_null_to_null(value))
12 | include (entity_id)
13 | where av;
14 |
15 | drop index av_index;
16 |
17 | alter index av_ignore_nulls_index rename to av_index;
18 |
--------------------------------------------------------------------------------
/server/resources/migrations/54_on_delete_reverse.down.sql:
--------------------------------------------------------------------------------
1 | alter table attrs drop column on_delete_reverse;
2 |
--------------------------------------------------------------------------------
/server/resources/migrations/54_on_delete_reverse.up.sql:
--------------------------------------------------------------------------------
1 | alter table attrs add column on_delete_reverse attr_on_delete;
2 |
--------------------------------------------------------------------------------
/server/resources/migrations/55_add_storage_sweeper.down.sql:
--------------------------------------------------------------------------------
1 | drop index app_files_to_sweep_created_at_idx;
2 | drop index app_files_to_sweep_process_id_updated_at_idx;
3 |
4 | drop trigger update_updated_at_trigger on app_files_to_sweep;
5 |
6 | alter table app_files_to_sweep drop column process_id;
7 | alter table app_files_to_sweep drop column updated_at;
8 | alter table app_files_to_sweep alter column created_at type timestamp without time zone;
9 |
--------------------------------------------------------------------------------
/server/resources/migrations/55_add_storage_sweeper.up.sql:
--------------------------------------------------------------------------------
1 | alter table app_files_to_sweep alter column created_at type timestamp with time zone
2 | using created_at at time ZONE 'UTC';
3 | alter table app_files_to_sweep add column updated_at timestamp with time zone not null default now();;
4 | alter table app_files_to_sweep add column process_id text;
5 |
6 | create trigger update_updated_at_trigger
7 | before update on app_files_to_sweep for each row
8 | execute function update_updated_at_column();
9 |
10 | create index app_files_to_sweep_process_id_updated_at_idx on app_files_to_sweep (process_id, updated_at);
11 | create index app_files_to_sweep_created_at_idx ON app_files_to_sweep (created_at);
12 |
--------------------------------------------------------------------------------
/server/resources/migrations/57_apps_deletion.down.sql:
--------------------------------------------------------------------------------
1 | alter table
2 | apps drop column if exists deletion_marked_at;
3 |
--------------------------------------------------------------------------------
/server/resources/migrations/57_apps_deletion.up.sql:
--------------------------------------------------------------------------------
1 | alter table
2 | apps
3 | add
4 | column deletion_marked_at timestamp with time zone;
5 |
6 | create index if not exists idx_apps_deletion_marked_at on apps (deletion_marked_at);
7 |
--------------------------------------------------------------------------------
/server/resources/migrations/58_instant_oauth_provider.down.sql:
--------------------------------------------------------------------------------
1 | drop table instant_user_oauth_access_tokens;
2 | drop table instant_user_oauth_refresh_tokens;
3 | drop table instant_oauth_app_redirects;
4 | drop table instant_oauth_app_codes;
5 | drop table instant_oauth_app_client_secrets;
6 | drop table instant_oauth_app_clients;
7 | drop table instant_oauth_apps;
8 | drop type instant_oauth_app_redirect_status;
9 |
--------------------------------------------------------------------------------
/server/resources/migrations/59_is_required.down.sql:
--------------------------------------------------------------------------------
1 | alter table attrs drop column is_required;
2 |
--------------------------------------------------------------------------------
/server/resources/migrations/59_is_required.up.sql:
--------------------------------------------------------------------------------
1 | alter table attrs add column is_required boolean not null default false;
--------------------------------------------------------------------------------
/server/resources/migrations/60_statistics.down.sql:
--------------------------------------------------------------------------------
1 | drop statistics triples_attr_value_mcv;
2 |
3 | alter table triples alter column attr_id set statistics -1;
4 | alter table triples alter column value set statistics -1;
5 |
--------------------------------------------------------------------------------
/server/resources/migrations/60_statistics.up.sql:
--------------------------------------------------------------------------------
1 | create statistics if not exists triples_attr_value_mcv (mcv)
2 | on attr_id, checked_data_type, ave, value
3 | from triples;
4 |
5 | alter table triples alter column attr_id set statistics 2500;
6 | alter table triples alter column value set statistics 2500;
7 |
--------------------------------------------------------------------------------
/server/resources/migrations/61_seed_test_user.down.sql:
--------------------------------------------------------------------------------
1 | delete from instant_users where email = 'testuser@instantdb.com';
2 |
--------------------------------------------------------------------------------
/server/resources/migrations/61_seed_test_user.up.sql:
--------------------------------------------------------------------------------
1 | insert into
2 | instant_users (id, email, created_at, google_sub)
3 | values
4 | (
5 | 'f487bef2-59f7-4176-9ad2-9f05c0c5db26',
6 | 'testuser@instantdb.com',
7 | '2023-01-23 09:48:35.941053',
8 | null
9 | ) on conflict do nothing;
10 |
--------------------------------------------------------------------------------
/server/resources/migrations/62_seed_ephemeral_app_creator.down.sql:
--------------------------------------------------------------------------------
1 | delete from
2 | instant_users
3 | where email in (
4 | 'hello+ephemeralappsdev@instantdb.com',
5 | 'hello+ephemeralapps@instantdb.com'
6 | );
7 |
--------------------------------------------------------------------------------
/server/resources/migrations/62_seed_ephemeral_app_creator.up.sql:
--------------------------------------------------------------------------------
1 | insert into
2 | instant_users (id, email, created_at, google_sub)
3 | values
4 | (
5 | 'dda67f26-6962-479e-b476-60e4b6963b74',
6 | 'hello+ephemeralappsdev@instantdb.com',
7 | '2024-04-08 17:20:17.644783',
8 | null
9 | ),
10 | (
11 | 'ee25bd4e-b968-4c1c-bde4-df046ef0dade',
12 | 'hello+ephemeralapps@instantdb.com',
13 | '2024-04-08 17:20:42.704454',
14 | null
15 | ) on conflict do nothing;
16 |
--------------------------------------------------------------------------------
/server/resources/migrations/63_seed_homepage_app.down.sql:
--------------------------------------------------------------------------------
1 | delete from apps where id = 'fc5a4977-910a-43d9-ac28-39c7837c1eb5';
2 |
--------------------------------------------------------------------------------
/server/resources/migrations/63_seed_homepage_app.up.sql:
--------------------------------------------------------------------------------
1 | with u_ins as (
2 | insert into
3 | instant_users (id, email)
4 | values
5 | (
6 | '6f0f64c9-207f-4b35-aec7-82739dcde58e',
7 | 'stopa@instantdb.com'
8 | ) on conflict (email) do nothing returning id
9 | ),
10 | u as (
11 | select
12 | id
13 | from
14 | u_ins
15 | union
16 | all
17 | select
18 | id
19 | from
20 | instant_users
21 | where
22 | email = 'stopa@instantdb.com'
23 | ),
24 | app_ins as (
25 | insert into
26 | apps (id, creator_id, title)
27 | select
28 | 'fc5a4977-910a-43d9-ac28-39c7837c1eb5',
29 | id,
30 | 'homepage'
31 | from
32 | u on conflict do nothing
33 | )
34 | insert into
35 | rules (app_id, code)
36 | values
37 | (
38 | 'fc5a4977-910a-43d9-ac28-39c7837c1eb5',
39 | '{ "$default": { "allow": { "$default": "false" } } }'
40 | ) on conflict do nothing;
41 |
--------------------------------------------------------------------------------
/server/resources/migrations/64_better_uuid_constraint.down.sql:
--------------------------------------------------------------------------------
1 | alter table triples drop constraint valid_ref_value;
2 |
3 | drop function public.triples_extract_uuid_value(value jsonb);
4 |
5 | drop function public.triples_valid_ref_value(t public.triples);
6 |
--------------------------------------------------------------------------------
/server/resources/migrations/65_drop_old_constraint.down.sql:
--------------------------------------------------------------------------------
1 | ALTER TABLE triples
2 | ADD CONSTRAINT ref_values_are_uuid
3 | CHECK (
4 | CASE WHEN eav OR vae THEN
5 | jsonb_typeof(value) = 'string' AND
6 | (value->>0)::uuid IS NOT NULL
7 | ELSE TRUE
8 | END
9 | )
10 | not valid;
11 |
--------------------------------------------------------------------------------
/server/resources/migrations/65_drop_old_constraint.up.sql:
--------------------------------------------------------------------------------
1 | alter table triples drop constraint if exists ref_values_are_uuid;
2 |
--------------------------------------------------------------------------------
/server/resources/migrations/66_indexing_jobs_error_data.down.sql:
--------------------------------------------------------------------------------
1 | alter table indexing_jobs drop column error_data;
--------------------------------------------------------------------------------
/server/resources/migrations/66_indexing_jobs_error_data.up.sql:
--------------------------------------------------------------------------------
1 | alter table indexing_jobs add column error_data jsonb;
2 |
--------------------------------------------------------------------------------
/server/resources/migrations/67_personal_access_token_lookup.down.sql:
--------------------------------------------------------------------------------
1 | alter table instant_personal_access_tokens drop column lookup_key;
2 |
--------------------------------------------------------------------------------
/server/resources/migrations/67_personal_access_token_lookup.up.sql:
--------------------------------------------------------------------------------
1 | alter table instant_personal_access_tokens add column lookup_key bytea;
2 |
3 | update instant_personal_access_tokens set lookup_key = sha256(cast(cast(id as text) as bytea));
4 |
5 | alter table instant_personal_access_tokens alter column lookup_key set not null;
6 |
7 | create index on instant_personal_access_tokens (lookup_key);
8 |
--------------------------------------------------------------------------------
/server/resources/migrations/68_attrs_etype_label_schema.down.sql:
--------------------------------------------------------------------------------
1 | DROP TRIGGER IF EXISTS trg_attrs_unique_names ON attrs;
2 | DROP FUNCTION check_attrs_unique_names;
3 |
4 | ALTER TABLE attrs DROP CONSTRAINT attrs_etype_label_unique;
5 | ALTER TABLE attrs DROP CONSTRAINT attrs_reverse_etype_label_unique;
6 |
7 | ALTER TABLE attrs DROP COLUMN etype;
8 | ALTER TABLE attrs DROP COLUMN label;
9 | ALTER TABLE attrs DROP COLUMN reverse_etype;
10 | ALTER TABLE attrs DROP COLUMN reverse_label;
11 |
--------------------------------------------------------------------------------
/server/resources/migrations/69_attrs_etype_label_data.down.sql:
--------------------------------------------------------------------------------
1 | ALTER TABLE attrs ALTER COLUMN etype DROP NOT NULL;
2 | ALTER TABLE attrs ALTER COLUMN label DROP NOT NULL;
3 |
--------------------------------------------------------------------------------
/server/resources/migrations/69_attrs_etype_label_data.up.sql:
--------------------------------------------------------------------------------
1 | UPDATE attrs
2 | SET etype = idents.etype,
3 | label = idents.label
4 | FROM idents
5 | WHERE attrs.forward_ident = idents.id;
6 |
7 | ALTER TABLE attrs ALTER COLUMN etype SET NOT NULL;
8 | ALTER TABLE attrs ALTER COLUMN label SET NOT NULL;
9 |
10 | UPDATE attrs
11 | SET reverse_etype = idents.etype,
12 | reverse_label = idents.label
13 | FROM idents
14 | WHERE attrs.reverse_ident = idents.id;
15 |
--------------------------------------------------------------------------------
/server/resources/migrations/70_improve_file_system_attrs.down.sql:
--------------------------------------------------------------------------------
1 | -- no-op
2 |
--------------------------------------------------------------------------------
/server/resources/migrations/70_improve_file_system_attrs.up.sql:
--------------------------------------------------------------------------------
1 | update
2 | attrs a
3 | set
4 | is_required = true
5 | where
6 | -- $files.path
7 | a.id = '96653230-13ff-ffff-2a34-f04cffffffff';
8 |
9 | update
10 | attrs a
11 | set
12 | checked_data_type = 'string'::checked_data_type
13 | where
14 | -- $files.url
15 | a.id = '96653230-13ff-ffff-2a35-48afffffffff';
16 |
--------------------------------------------------------------------------------
/server/scripts/export/copy_apps.sql:
--------------------------------------------------------------------------------
1 | COPY (SELECT id, title, created_at FROM apps WHERE id = :'app_id') TO STDOUT
2 |
--------------------------------------------------------------------------------
/server/scripts/export/copy_attrs.sql:
--------------------------------------------------------------------------------
1 | COPY (SELECT * FROM attrs WHERE app_id = :'app_id') TO STDOUT
2 |
--------------------------------------------------------------------------------
/server/scripts/export/copy_idents.sql:
--------------------------------------------------------------------------------
1 | COPY (SELECT * FROM idents WHERE app_id = :'app_id') TO STDOUT
2 |
--------------------------------------------------------------------------------
/server/scripts/export/copy_rules.sql:
--------------------------------------------------------------------------------
1 | COPY (SELECT * FROM rules WHERE app_id = :'app_id') TO STDOUT
2 |
--------------------------------------------------------------------------------
/server/scripts/export/copy_triples.sql:
--------------------------------------------------------------------------------
1 | COPY (SELECT * FROM triples WHERE app_id = :'app_id') TO STDOUT
2 |
--------------------------------------------------------------------------------
/server/scripts/install_dev_certs.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | set -o errexit -o nounset -o pipefail -o xtrace
3 | cd `dirname $0`/..
4 |
5 | brew install mkcert
6 | brew install nss
7 |
8 | mkcert -install
9 | mkdir -p dev-resources/certs
10 | cd dev-resources/certs
11 | DOMAIN="dev.instantdb.com"
12 | mkcert ${DOMAIN}
13 |
14 | CA_ROOT="$(mkcert -CAROOT)/rootCA.pem"
15 |
16 | cat ${DOMAIN}.pem "$CA_ROOT" > chain.pem
17 | echo "USE PASSWORD: changeit"
18 | openssl pkcs12 -export -inkey ${DOMAIN}-key.pem -in chain.pem -out dev.p12
19 | keytool -importkeystore -storepass changeit -srckeystore dev.p12 -srcstoretype pkcs12 -destkeystore dev.jks -deststoretype pkcs12
20 | # verify
21 | keytool -list -v -storepass changeit -keystore dev.jks
22 |
23 | rm dev.p12
24 | rm chain.pem
--------------------------------------------------------------------------------
/server/scripts/prod_ssh.sh:
--------------------------------------------------------------------------------
1 | while [[ "$#" -gt 0 ]]; do
2 | case $1 in
3 | --instance-id) instance_id="$2"; shift ;;
4 | *) echo "Unknown parameter passed: $1"; exit 1 ;;
5 | esac
6 | shift
7 | done
8 |
9 | if [ -z "$instance_id" ]; then
10 | instance_id=$(
11 | aws ec2 describe-instances \
12 | --filter "Name=tag:elasticbeanstalk:environment-name,Values=Instant-docker-prod-env-2" \
13 | --query "Reservations[].Instances[?State.Name == 'running'].InstanceId[]" \
14 | --output text
15 | )
16 | fi
17 |
18 | echo "Opening SSH connection to $instance_id"
19 |
20 | aws ssm start-session \
21 | --target "$instance_id" \
22 | --region "us-east-1"
23 |
--------------------------------------------------------------------------------
/server/scripts/yourkit_tunnel.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | # set -x
3 | # set -e
4 |
5 | port=10001 # Default port
6 |
7 | while [[ "$#" -gt 0 ]]; do
8 | case $1 in
9 | --instance-id) instance_id="$2"; shift ;;
10 | --port) port="$2"; shift ;;
11 | *) echo "Unknown parameter passed: $1"; exit 1 ;;
12 | esac
13 | shift
14 | done
15 |
16 | if [ -z "$instance_id" ]; then
17 | instance_id=$(
18 | aws ec2 describe-instances \
19 | --filter "Name=tag:elasticbeanstalk:environment-name,Values=Instant-docker-prod-env-2" \
20 | --query "Reservations[].Instances[?State.Name == 'running'].InstanceId[]" \
21 | --output text
22 | )
23 | fi
24 |
25 | echo "Setting up tunnel to $instance_id on port $port"
26 |
27 | aws ssm start-session \
28 | --document-name "AWS-StartPortForwardingSession" \
29 | --target "$instance_id" \
30 | --parameters "{\"portNumber\":[\"10001\"],\"localPortNumber\":[\"$port\"]}" \
31 | --region "us-east-1"
32 |
33 | echo "Tunnel closed"
34 |
--------------------------------------------------------------------------------
/server/src/instant/comment.clj:
--------------------------------------------------------------------------------
1 | (ns instant.comment)
2 |
3 | (defn zeneca-app!
4 | []
5 | (let [{:keys [id] :as z} ((resolve 'instant.dash.ephemeral-app/create!)
6 | {:title "c-zeneca"})]
7 | ((resolve 'instant.data.bootstrap/add-zeneca-to-app!) id)
8 | z))
9 |
10 | (defn empty-app!
11 | []
12 | ((resolve 'instant.dash.ephemeral-app/create!) {:title "c-empty-app"}))
13 |
--------------------------------------------------------------------------------
/server/src/instant/data/constants.clj:
--------------------------------------------------------------------------------
1 | (ns instant.data.constants)
2 |
3 | (def test-user-id #uuid "f487bef2-59f7-4176-9ad2-9f05c0c5db26")
4 |
--------------------------------------------------------------------------------
/server/src/instant/db/model/transaction.clj:
--------------------------------------------------------------------------------
1 | (ns instant.db.model.transaction
2 | (:require
3 | [instant.jdbc.sql :as sql]
4 | [instant.jdbc.aurora :as aurora]))
5 |
6 | (defn create!
7 | ([params] (create! (aurora/conn-pool :write) params))
8 | ([conn {:keys [app-id]}]
9 | (sql/execute-one! ::create!
10 | conn
11 | ["INSERT INTO transactions (app_id) VALUES (?::uuid)"
12 | app-id])))
13 |
--------------------------------------------------------------------------------
/server/src/instant/db/model/triple_cols.clj:
--------------------------------------------------------------------------------
1 | (ns instant.db.model.triple-cols)
2 |
3 | ;; Prevent a circular-dependency since attr-model needs these
4 | (def triple-cols
5 | [:app-id :entity-id :attr-id :value :value-md5 :ea :eav :av :ave :vae :checked-data-type])
6 |
--------------------------------------------------------------------------------
/server/src/instant/grab.clj:
--------------------------------------------------------------------------------
1 | (ns instant.grab
2 | "A handy lib that makes sure some function only runs _once_,
3 | across processes and time."
4 | (:require
5 | [instant.jdbc.sql :as sql]
6 | [instant.jdbc.aurora :as aurora])
7 | (:import
8 | (java.time LocalDate)))
9 |
10 | (defn- try-grab!
11 | "If INSERT succeeds, we'll get back a row with a single item.
12 | If INSERT fails, it means the key already exists, the query
13 | will return an empty seq."
14 | [conn k]
15 | (boolean
16 | (seq
17 | (sql/execute! conn ["INSERT INTO grabs (id)
18 | VALUES (?)
19 | ON CONFLICT (id)
20 | DO NOTHING RETURNING id" k]))))
21 |
22 | (defn run-once! [k f]
23 | (if (try-grab! (aurora/conn-pool :write) k)
24 | (f)
25 | :no-op))
26 |
27 | (comment
28 | (run-once! (str (LocalDate/now)) (fn [] (println "grabbed foo"))))
29 |
--------------------------------------------------------------------------------
/server/src/instant/reactive/receive_queue.clj:
--------------------------------------------------------------------------------
1 | (ns instant.reactive.receive-queue
2 | (:require
3 | [instant.grouped-queue :as grouped-queue]))
4 |
5 | (declare receive-q)
6 |
7 | (defn put!
8 | ([item]
9 | (grouped-queue/put! receive-q item))
10 | ([q item]
11 | (grouped-queue/put! q item)))
12 |
13 | (defn start [q]
14 | (.bindRoot #'receive-q q))
15 |
16 | (defn stop []
17 | (when (bound? #'receive-q)
18 | (grouped-queue/stop receive-q)
19 | (.unbindRoot #'receive-q)))
20 |
--------------------------------------------------------------------------------
/server/src/instant/scratch/backtest_vars.clj:
--------------------------------------------------------------------------------
1 | (ns instant.scratch.backtest-vars)
2 |
3 | (def ^:dynamic *use-new* false)
4 |
--------------------------------------------------------------------------------
/server/src/instant/storage/beta.clj:
--------------------------------------------------------------------------------
1 | (ns instant.storage.beta
2 | (:require [instant.flags :as flags]
3 | [instant.config :as config]
4 | [instant.util.exception :as ex]))
5 |
6 | (defn assert-storage-enabled! [app-id]
7 | (if (= :prod (config/get-env))
8 | (ex/assert-permitted! :storage-enabled? app-id (not (flags/storage-disabled? app-id)))
9 | true))
10 |
--------------------------------------------------------------------------------
/server/src/instant/util/delay.clj:
--------------------------------------------------------------------------------
1 | (ns instant.util.delay
2 | (:import
3 | (java.util.concurrent Callable ScheduledFuture ScheduledThreadPoolExecutor TimeUnit)))
4 |
5 | (defn cpu-count []
6 | (.availableProcessors (Runtime/getRuntime)))
7 |
8 | (defn make-pool! [& {:keys [thread-count]
9 | :or {thread-count (+ 2 (cpu-count))}}]
10 | (ScheduledThreadPoolExecutor. thread-count))
11 |
12 | (defn delay-fn ^ScheduledFuture [^ScheduledThreadPoolExecutor thread-pool ^Long delay-ms ^Callable f]
13 | (.schedule thread-pool f delay-ms TimeUnit/MILLISECONDS))
14 |
15 | (defn repeat-fn ^ScheduledFuture [^ScheduledThreadPoolExecutor thread-pool delay-ms f]
16 | (.scheduleAtFixedRate thread-pool f delay-ms delay-ms TimeUnit/MILLISECONDS))
17 |
18 | (defn shutdown-pool! [^ScheduledThreadPoolExecutor pool]
19 | (.shutdown pool))
20 |
--------------------------------------------------------------------------------
/server/src/instant/util/lang.clj:
--------------------------------------------------------------------------------
1 | (ns instant.util.lang
2 | (:import
3 | (clojure.lang Var Var$Unbound)
4 | (java.lang AutoCloseable)))
5 |
6 | (defn close [o]
7 | (when (and o (not (instance? Var$Unbound o)))
8 | (AutoCloseable/.close o))
9 | o)
10 |
11 | (defmacro set-var! [var val]
12 | `(Var/.doReset (var ~var) ~val))
13 |
14 | (defmacro clear-var!
15 | ([var]
16 | `(clear-var ~var close))
17 | ([^Var var method]
18 | `(let [var# (var ~var)
19 | val# @var#]
20 | (when (and val# (not (instance? Var$Unbound val#)))
21 | (~method val#)
22 | (Var/.doReset var# nil)))))
23 |
--------------------------------------------------------------------------------
/server/src/instant/util/number.clj:
--------------------------------------------------------------------------------
1 | (ns instant.util.number)
2 |
3 | (defn parse-int [s default]
4 | (try
5 | (Integer/parseInt s)
6 | (catch Exception _ default)))
7 |
8 | (comment
9 | (parse-int "123" 0)
10 | (parse-int "abc" 0)
11 | (parse-int 123 0))
12 |
--------------------------------------------------------------------------------
/server/src/instant/util/spec.clj:
--------------------------------------------------------------------------------
1 | (ns instant.util.spec
2 | (:require [clojure.spec.alpha :as s]
3 | [clojure.string :as string]))
4 |
5 | (s/def ::non-blank-string
6 | (s/and string? (complement string/blank?)))
7 |
8 | (defn conform-throwing [spec value]
9 | (let [parsed (s/conform spec value)]
10 | (if (s/invalid? parsed)
11 | (throw (ex-info "Invalid input" (s/explain-data spec value)))
12 | parsed)))
13 |
14 | (defn tagged-as?
15 | "Given a tagged tuple: [:foo v], returns true if the tag matches"
16 | [tag x]
17 | (and (coll? x) (= tag (first x))))
18 |
19 | (defn tagged-unwrap
20 | "Unwraps a tagged tuple: [:foo v] => v"
21 | [x]
22 | (and (coll? x) (second x)))
23 |
24 |
--------------------------------------------------------------------------------
/server/src/java/instant/SpanTrackException.java:
--------------------------------------------------------------------------------
1 | package instant;
2 |
3 | // Creates an exception without a stack trace
4 | public class SpanTrackException extends Throwable {
5 | public SpanTrackException(String spanId) {
6 | super(spanId, null, true, false);
7 | }
8 | }
9 |
--------------------------------------------------------------------------------
/server/test/instant/storage/s3_test.clj:
--------------------------------------------------------------------------------
1 | (ns instant.storage.s3-test
2 | (:require [clojure.test :as test :refer [deftest is]]
3 | [instant.storage.s3 :as storage-s3]
4 | [instant.util.date :as date-util])
5 | (:import [java.time ZonedDateTime]))
6 |
7 | (deftest bucketed-zdate
8 | (let [tue-9-30-pm (ZonedDateTime/parse "2025-03-04T21:30:48.467889Z[UTC]")
9 | start-of-day-instant (.toInstant (ZonedDateTime/parse "2025-03-04T00:00:00.000000Z[UTC]"))]
10 | (with-redefs [date-util/utc-now (fn [] tue-9-30-pm)]
11 | (is (= start-of-day-instant (storage-s3/bucketed-signing-instant))))))
12 |
13 | (comment
14 | (test/run-tests *ns*))
15 |
--------------------------------------------------------------------------------
/server/test/instant/util/semver_test.clj:
--------------------------------------------------------------------------------
1 | (ns instant.util.semver-test
2 | (:require [instant.util.semver :as semver]
3 | [clojure.test :refer [deftest is]]))
4 |
5 | (deftest semver-parse
6 | (is (= {:major 1 :minor 10 :patch 1000 :dev? true}
7 | (semver/parse "v1.10.1000-dev")))
8 |
9 | (is (= {:major 1 :minor 10 :patch 1000 :dev? true}
10 | (semver/parse "1.10.1000-dev")))
11 |
12 | (is (= {:major 1 :minor 2 :patch 3 :dev? false}
13 | (semver/parse "1.2.3"))))
14 |
15 | (deftest semver-compare
16 | (is (= ["v0.1.2" "v0.1.2-dev" "1.1.2" "1.2.3" "2.3.3-dev" "2.3.4"]
17 | (sort semver/compare-semver
18 | (shuffle ["v0.1.2"
19 | "v0.1.2-dev"
20 | "1.1.2"
21 | "1.2.3"
22 | "2.3.4"
23 | "2.3.3-dev"])))))
24 |
--------------------------------------------------------------------------------
/vercel.json:
--------------------------------------------------------------------------------
1 | {
2 | "version": 2,
3 | "public": false,
4 | "github": {
5 | "enabled": false
6 | }
7 | }
8 |
--------------------------------------------------------------------------------