├── .gitignore ├── .prettierrc ├── README.md ├── apps ├── chat │ ├── README.md │ ├── index.html │ ├── package.json │ ├── public │ │ └── favicon.ico │ ├── src │ │ ├── app.tsx │ │ ├── client.tsx │ │ ├── livestore.worker.ts │ │ ├── livestore │ │ │ ├── queries.ts │ │ │ └── schema.ts │ │ ├── server.ts │ │ └── util │ │ │ └── store-id.ts │ ├── tsconfig.json │ ├── vite.config.ts │ └── wrangler.jsonc ├── linearlite │ ├── README.md │ ├── index.html │ ├── package.json │ ├── public │ │ ├── favicon.ico │ │ ├── fonts │ │ │ ├── inter-extrabold.woff │ │ │ ├── inter-extrabold.woff2 │ │ │ ├── inter-medium.woff │ │ │ ├── inter-medium.woff2 │ │ │ ├── inter-regular.woff │ │ │ ├── inter-regular.woff2 │ │ │ ├── inter-semibold.woff │ │ │ └── inter-semibold.woff2 │ │ └── netlify.toml │ ├── src │ │ ├── app │ │ │ ├── app.tsx │ │ │ ├── contexts.ts │ │ │ ├── main.tsx │ │ │ ├── provider.tsx │ │ │ └── style.css │ │ ├── components │ │ │ ├── common │ │ │ │ ├── avatar.tsx │ │ │ │ ├── editor-menu.tsx │ │ │ │ ├── editor.tsx │ │ │ │ ├── menu-button.tsx │ │ │ │ ├── modal.tsx │ │ │ │ ├── priority-menu.tsx │ │ │ │ ├── shortcut.tsx │ │ │ │ └── status-menu.tsx │ │ │ ├── icons │ │ │ │ ├── backlog.tsx │ │ │ │ ├── canceled.tsx │ │ │ │ ├── done.tsx │ │ │ │ ├── filter.tsx │ │ │ │ ├── in-progress.tsx │ │ │ │ ├── index.tsx │ │ │ │ ├── linear-lite.tsx │ │ │ │ ├── livestore.tsx │ │ │ │ ├── new-issue.tsx │ │ │ │ ├── priority-high.tsx │ │ │ │ ├── priority-low.tsx │ │ │ │ ├── priority-medium.tsx │ │ │ │ ├── priority-none.tsx │ │ │ │ ├── priority-urgent.tsx │ │ │ │ ├── sidebar.tsx │ │ │ │ └── todo.tsx │ │ │ └── layout │ │ │ │ ├── board │ │ │ │ ├── card.tsx │ │ │ │ ├── column.tsx │ │ │ │ ├── draggable.tsx │ │ │ │ └── index.tsx │ │ │ │ ├── filters │ │ │ │ ├── filter-menu.tsx │ │ │ │ ├── header.tsx │ │ │ │ ├── index.tsx │ │ │ │ ├── priority-filter.tsx │ │ │ │ ├── sort-menu.tsx │ │ │ │ └── status-filter.tsx │ │ │ │ ├── index.tsx │ │ │ │ ├── issue │ │ │ │ ├── back-button.tsx │ │ │ │ ├── comment-input.tsx │ │ │ │ ├── comments.tsx │ │ │ │ ├── delete-button.tsx │ │ │ │ ├── description-input.tsx │ │ │ │ ├── index.tsx │ │ │ │ ├── new-issue-modal.tsx │ │ │ │ └── title-input.tsx │ │ │ │ ├── list │ │ │ │ ├── filtered-list.tsx │ │ │ │ ├── index.tsx │ │ │ │ ├── row.tsx │ │ │ │ └── virtual-row.tsx │ │ │ │ ├── search │ │ │ │ ├── index.tsx │ │ │ │ └── search-bar.tsx │ │ │ │ ├── sidebar │ │ │ │ ├── about-menu.tsx │ │ │ │ ├── about-modal.tsx │ │ │ │ ├── index.tsx │ │ │ │ ├── mobile-menu.tsx │ │ │ │ ├── new-issue-button.tsx │ │ │ │ ├── search-button.tsx │ │ │ │ └── theme-button.tsx │ │ │ │ └── toolbar │ │ │ │ ├── devtools-button.tsx │ │ │ │ ├── download-button.tsx │ │ │ │ ├── index.tsx │ │ │ │ ├── mobile-menu.tsx │ │ │ │ ├── reset-button.tsx │ │ │ │ ├── seed-input.tsx │ │ │ │ ├── share-button.tsx │ │ │ │ ├── sync-toggle.tsx │ │ │ │ ├── toolbar-button.tsx │ │ │ │ └── user-input.tsx │ │ ├── data │ │ │ ├── priority-options.ts │ │ │ ├── sorting-options.ts │ │ │ ├── status-options.ts │ │ │ └── theme-options.ts │ │ ├── hooks │ │ │ ├── useClickOutside.ts │ │ │ ├── useDebounce.ts │ │ │ └── useLockBodyScroll.ts │ │ ├── lib │ │ │ └── livestore │ │ │ │ ├── events.ts │ │ │ │ ├── queries.ts │ │ │ │ ├── schema │ │ │ │ ├── comment.ts │ │ │ │ ├── description.ts │ │ │ │ ├── filter-state.ts │ │ │ │ ├── frontend-state.ts │ │ │ │ ├── index.ts │ │ │ │ ├── issue.ts │ │ │ │ └── scroll-state.ts │ │ │ │ ├── seed.ts │ │ │ │ ├── utils.tsx │ │ │ │ └── worker.ts │ │ ├── server.ts │ │ ├── types │ │ │ ├── comment.ts │ │ │ ├── description.ts │ │ │ ├── issue.ts │ │ │ ├── priority.ts │ │ │ └── status.ts │ │ └── utils │ │ │ ├── format-date.ts │ │ │ ├── get-acronym.ts │ │ │ └── get-issue-tag.ts │ ├── tailwind.config.cjs │ ├── tsconfig.json │ ├── vite.config.ts │ └── wrangler.jsonc ├── react-router │ ├── .react-router │ │ └── types │ │ │ ├── +future.ts │ │ │ ├── +routes.ts │ │ │ ├── +server-build.d.ts │ │ │ └── app │ │ │ ├── +types │ │ │ └── root.ts │ │ │ └── routes │ │ │ └── +types │ │ │ └── home.ts │ ├── README.md │ ├── app │ │ ├── app.css │ │ ├── counter.tsx │ │ ├── entry.server.tsx │ │ ├── livestore │ │ │ ├── livestore.worker.ts │ │ │ └── schema.ts │ │ ├── root.tsx │ │ ├── routes.ts │ │ ├── routes │ │ │ └── home.tsx │ │ └── server.ts │ ├── package.json │ ├── public │ │ └── favicon.ico │ ├── react-router.config.ts │ ├── tsconfig.json │ ├── vite.config.ts │ └── wrangler.jsonc └── todomvc │ ├── README.md │ ├── index.html │ ├── package.json │ ├── public │ └── favicon.ico │ ├── src │ ├── app.tsx │ ├── client.tsx │ ├── components │ │ ├── Footer.tsx │ │ ├── Header.tsx │ │ └── MainSection.tsx │ ├── livestore.worker.ts │ ├── livestore │ │ ├── queries.ts │ │ └── schema.ts │ ├── server.ts │ └── util │ │ └── store-id.ts │ ├── tsconfig.json │ ├── vite.config.ts │ └── wrangler.jsonc ├── package-lock.json ├── package.json ├── patches └── @livestore+sync-cf+0.3.0.patch └── tsconfig.json /.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | lerna-debug.log* 8 | .pnpm-debug.log* 9 | 10 | # Diagnostic reports (https://nodejs.org/api/report.html) 11 | report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json 12 | 13 | # Runtime data 14 | pids 15 | *.pid 16 | *.seed 17 | *.pid.lock 18 | 19 | # Directory for instrumented libs generated by jscoverage/JSCover 20 | lib-cov 21 | 22 | # Coverage directory used by tools like istanbul 23 | coverage 24 | *.lcov 25 | 26 | # nyc test coverage 27 | .nyc_output 28 | 29 | # Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) 30 | .grunt 31 | 32 | # Bower dependency directory (https://bower.io/) 33 | bower_components 34 | 35 | # node-waf configuration 36 | .lock-wscript 37 | 38 | # Compiled binary addons (https://nodejs.org/api/addons.html) 39 | build/Release 40 | 41 | # Dependency directories 42 | node_modules/ 43 | jspm_packages/ 44 | 45 | # Snowpack dependency directory (https://snowpack.dev/) 46 | web_modules/ 47 | 48 | # TypeScript cache 49 | *.tsbuildinfo 50 | 51 | # Optional npm cache directory 52 | .npm 53 | 54 | # Optional eslint cache 55 | .eslintcache 56 | 57 | # Optional stylelint cache 58 | .stylelintcache 59 | 60 | # Microbundle cache 61 | .rpt2_cache/ 62 | .rts2_cache_cjs/ 63 | .rts2_cache_es/ 64 | .rts2_cache_umd/ 65 | 66 | # Optional REPL history 67 | .node_repl_history 68 | 69 | # Output of 'npm pack' 70 | *.tgz 71 | 72 | # Yarn Integrity file 73 | .yarn-integrity 74 | 75 | # dotenv environment variable files 76 | .env 77 | .env.development.local 78 | .env.test.local 79 | .env.production.local 80 | .env.local 81 | 82 | # parcel-bundler cache (https://parceljs.org/) 83 | .cache 84 | .parcel-cache 85 | 86 | # Next.js build output 87 | .next 88 | out 89 | 90 | # Nuxt.js build / generate output 91 | .nuxt 92 | dist 93 | 94 | # Gatsby files 95 | .cache/ 96 | # Comment in the public line in if your project uses Gatsby and not Next.js 97 | # https://nextjs.org/blog/next-9-1#public-directory-support 98 | # public 99 | 100 | # vuepress build output 101 | .vuepress/dist 102 | 103 | # vuepress v2.x temp and cache directory 104 | .temp 105 | .cache 106 | 107 | # vitepress build output 108 | **/.vitepress/dist 109 | 110 | # vitepress cache directory 111 | **/.vitepress/cache 112 | 113 | # Docusaurus cache and generated files 114 | .docusaurus 115 | 116 | # Serverless directories 117 | .serverless/ 118 | 119 | # FuseBox cache 120 | .fusebox/ 121 | 122 | # DynamoDB Local files 123 | .dynamodb/ 124 | 125 | # TernJS port file 126 | .tern-port 127 | 128 | # Stores VSCode versions used for testing VSCode extensions 129 | .vscode-test 130 | 131 | # yarn v2 132 | .yarn/cache 133 | .yarn/unplugged 134 | .yarn/build-state.yml 135 | .yarn/install-state.gz 136 | .pnp.* 137 | 138 | build 139 | 140 | 141 | .wrangler 142 | .dev.vars 143 | 144 | .DS_Store -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "trailingComma": "none" 3 | } 4 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## livestore ⨉ cloudflare 2 | 3 | experiments with livestore on cloudflare workers 4 | 5 | - livestore's cf sync has been patched so it uses the DO's storage instead of D1 6 | -------------------------------------------------------------------------------- /apps/chat/README.md: -------------------------------------------------------------------------------- 1 | ## chat (only stubs, not implemented yet) 2 | 3 | ### dev 4 | 5 | `npm i && npm start` 6 | 7 | ### deploy 8 | 9 | `npm i && npm run deploy` 10 | 11 | (don't forget to change the value of `VITE_LIVESTORE_SYNC_URL` in `package.json`) 12 | -------------------------------------------------------------------------------- /apps/chat/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 |
4 | 5 | 6 |16 | LinearLite is an example of a collaboration application using a 17 | local-first approach, obviously inspired by{" "} 18 | 23 | Linear 24 | 25 | . 26 |
27 |28 | It's built using{" "} 29 | 34 | LiveStore 35 | 36 | , a local-first sync layer for web and mobile apps. 37 |
38 |{details}
108 | {stack && ( 109 |
110 | {stack}
111 |
112 | )}
113 |