dirsql 0.3.5__tar.gz → 0.3.7__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (135) hide show
  1. {dirsql-0.3.5 → dirsql-0.3.7}/Cargo.lock +1 -1
  2. {dirsql-0.3.5 → dirsql-0.3.7}/PKG-INFO +8 -8
  3. {dirsql-0.3.5/packages/python → dirsql-0.3.7}/README.md +6 -6
  4. dirsql-0.3.7/docs/.vitepress/config.ts +83 -0
  5. {dirsql-0.3.5 → dirsql-0.3.7}/docs/AGENTS.md +6 -0
  6. {dirsql-0.3.5 → dirsql-0.3.7}/docs/api/index.md +4 -4
  7. {dirsql-0.3.5/packages/python/docs/guide → dirsql-0.3.7/docs/cli}/config.md +8 -20
  8. dirsql-0.3.5/docs/guide/cli.md → dirsql-0.3.7/docs/cli/http-api.md +12 -58
  9. dirsql-0.3.7/docs/cli/index.md +73 -0
  10. {dirsql-0.3.5/docs/guide → dirsql-0.3.7/docs/cli}/init.md +4 -4
  11. dirsql-0.3.7/docs/cli/server.md +59 -0
  12. {dirsql-0.3.5/packages/python → dirsql-0.3.7}/docs/getting-started.md +11 -10
  13. {dirsql-0.3.5/packages/rust → dirsql-0.3.7}/docs/guide/async.md +4 -3
  14. {dirsql-0.3.5/packages/python → dirsql-0.3.7}/docs/guide/crdt.md +4 -3
  15. {dirsql-0.3.5/packages/rust → dirsql-0.3.7}/docs/guide/querying.md +4 -0
  16. {dirsql-0.3.5/packages/rust → dirsql-0.3.7}/docs/guide/tables.md +28 -27
  17. {dirsql-0.3.5/packages/rust → dirsql-0.3.7}/docs/guide/watching.md +8 -3
  18. {dirsql-0.3.5/packages/rust → dirsql-0.3.7}/docs/index.md +4 -3
  19. dirsql-0.3.7/docs/tests/unit/config.test.ts +22 -0
  20. {dirsql-0.3.5 → dirsql-0.3.7}/packages/python/Cargo.toml +1 -1
  21. {dirsql-0.3.5 → dirsql-0.3.7/packages/python}/README.md +6 -6
  22. dirsql-0.3.7/packages/python/docs/.vitepress/config.ts +83 -0
  23. {dirsql-0.3.5 → dirsql-0.3.7}/packages/python/docs/AGENTS.md +6 -0
  24. {dirsql-0.3.5/packages/rust → dirsql-0.3.7/packages/python}/docs/api/index.md +4 -4
  25. {dirsql-0.3.5/packages/rust/docs/guide → dirsql-0.3.7/packages/python/docs/cli}/config.md +8 -20
  26. dirsql-0.3.5/packages/rust/docs/guide/cli.md → dirsql-0.3.7/packages/python/docs/cli/http-api.md +12 -58
  27. dirsql-0.3.7/packages/python/docs/cli/index.md +73 -0
  28. {dirsql-0.3.5/packages/rust/docs/guide → dirsql-0.3.7/packages/python/docs/cli}/init.md +4 -4
  29. dirsql-0.3.7/packages/python/docs/cli/server.md +59 -0
  30. {dirsql-0.3.5 → dirsql-0.3.7/packages/python}/docs/getting-started.md +11 -10
  31. {dirsql-0.3.5 → dirsql-0.3.7}/packages/python/docs/guide/async.md +4 -3
  32. {dirsql-0.3.5/packages/rust → dirsql-0.3.7/packages/python}/docs/guide/crdt.md +4 -3
  33. {dirsql-0.3.5 → dirsql-0.3.7}/packages/python/docs/guide/querying.md +4 -0
  34. {dirsql-0.3.5 → dirsql-0.3.7}/packages/python/docs/guide/tables.md +28 -27
  35. {dirsql-0.3.5 → dirsql-0.3.7}/packages/python/docs/guide/watching.md +8 -3
  36. {dirsql-0.3.5 → dirsql-0.3.7/packages/python}/docs/index.md +4 -3
  37. dirsql-0.3.7/packages/python/docs/tests/unit/config.test.ts +22 -0
  38. {dirsql-0.3.5 → dirsql-0.3.7}/packages/python/src/lib.rs +3 -4
  39. {dirsql-0.3.5 → dirsql-0.3.7}/packages/python/tests/integration/test_async_dirsql.py +28 -16
  40. {dirsql-0.3.5 → dirsql-0.3.7}/packages/python/tests/integration/test_dirsql.py +59 -34
  41. {dirsql-0.3.5 → dirsql-0.3.7}/packages/python/tests/integration/test_docs_examples.py +56 -25
  42. {dirsql-0.3.5 → dirsql-0.3.7}/packages/python/tests/integration/test_docs_gaps.py +10 -6
  43. {dirsql-0.3.5 → dirsql-0.3.7}/packages/python/tests/integration/test_persist.py +12 -5
  44. {dirsql-0.3.5 → dirsql-0.3.7}/packages/rust/Cargo.toml +3 -1
  45. {dirsql-0.3.5 → dirsql-0.3.7}/packages/rust/README.md +4 -1
  46. {dirsql-0.3.5/packages/python → dirsql-0.3.7/packages/rust}/docs/api/index.md +4 -4
  47. {dirsql-0.3.5/docs/guide → dirsql-0.3.7/packages/rust/docs/cli}/config.md +8 -20
  48. dirsql-0.3.5/packages/python/docs/guide/cli.md → dirsql-0.3.7/packages/rust/docs/cli/http-api.md +12 -58
  49. dirsql-0.3.7/packages/rust/docs/cli/index.md +73 -0
  50. {dirsql-0.3.5/packages/python/docs/guide → dirsql-0.3.7/packages/rust/docs/cli}/init.md +4 -4
  51. dirsql-0.3.7/packages/rust/docs/cli/server.md +59 -0
  52. {dirsql-0.3.5 → dirsql-0.3.7}/packages/rust/docs/getting-started.md +11 -10
  53. {dirsql-0.3.5 → dirsql-0.3.7/packages/rust}/docs/guide/async.md +4 -3
  54. {dirsql-0.3.5 → dirsql-0.3.7/packages/rust}/docs/guide/crdt.md +4 -3
  55. {dirsql-0.3.5 → dirsql-0.3.7/packages/rust}/docs/guide/querying.md +4 -0
  56. {dirsql-0.3.5 → dirsql-0.3.7/packages/rust}/docs/guide/tables.md +28 -27
  57. {dirsql-0.3.5 → dirsql-0.3.7/packages/rust}/docs/guide/watching.md +8 -3
  58. {dirsql-0.3.5/packages/python → dirsql-0.3.7/packages/rust}/docs/index.md +4 -3
  59. {dirsql-0.3.5 → dirsql-0.3.7}/packages/rust/src/bin/dirsql.rs +53 -8
  60. {dirsql-0.3.5 → dirsql-0.3.7}/packages/rust/src/lib.rs +30 -29
  61. {dirsql-0.3.5 → dirsql-0.3.7}/packages/rust/src/persist.rs +6 -6
  62. {dirsql-0.3.5 → dirsql-0.3.7}/packages/rust/tests/async_sdk.rs +9 -11
  63. {dirsql-0.3.5 → dirsql-0.3.7}/packages/rust/tests/cli_e2e.rs +45 -5
  64. {dirsql-0.3.5 → dirsql-0.3.7}/packages/rust/tests/cli_integration.rs +28 -15
  65. {dirsql-0.3.5 → dirsql-0.3.7}/packages/rust/tests/docs_examples.rs +43 -26
  66. {dirsql-0.3.5 → dirsql-0.3.7}/packages/rust/tests/docs_gaps.rs +15 -22
  67. {dirsql-0.3.5 → dirsql-0.3.7}/packages/rust/tests/init_e2e.rs +1 -4
  68. {dirsql-0.3.5 → dirsql-0.3.7}/packages/rust/tests/persist.rs +11 -13
  69. {dirsql-0.3.5 → dirsql-0.3.7}/packages/rust/tests/readonly_query.rs +2 -1
  70. {dirsql-0.3.5 → dirsql-0.3.7}/packages/rust/tests/sdk.rs +65 -40
  71. {dirsql-0.3.5 → dirsql-0.3.7}/pyproject.toml +1 -1
  72. dirsql-0.3.5/docs/.vitepress/config.ts +0 -65
  73. dirsql-0.3.5/docs/tests/unit/config.test.ts +0 -9
  74. dirsql-0.3.5/packages/python/docs/.vitepress/config.ts +0 -65
  75. dirsql-0.3.5/packages/python/docs/tests/unit/config.test.ts +0 -9
  76. {dirsql-0.3.5 → dirsql-0.3.7}/Cargo.toml +0 -0
  77. {dirsql-0.3.5 → dirsql-0.3.7}/dirsql/__init__.py +0 -0
  78. {dirsql-0.3.5 → dirsql-0.3.7}/dirsql/_async.py +0 -0
  79. {dirsql-0.3.5 → dirsql-0.3.7}/dirsql/_cli/__init__.py +0 -0
  80. {dirsql-0.3.5 → dirsql-0.3.7}/dirsql/_cli/binary_path.py +0 -0
  81. {dirsql-0.3.5 → dirsql-0.3.7}/dirsql/_cli/is_windows.py +0 -0
  82. {dirsql-0.3.5 → dirsql-0.3.7}/dirsql/_cli/main.py +0 -0
  83. {dirsql-0.3.5 → dirsql-0.3.7}/dirsql/test_async.py +0 -0
  84. {dirsql-0.3.5 → dirsql-0.3.7}/docs/.claude/CLAUDE.md +0 -0
  85. {dirsql-0.3.5 → dirsql-0.3.7}/docs/.vitepress/theme/index.ts +0 -0
  86. {dirsql-0.3.5 → dirsql-0.3.7}/docs/.vitepress/theme/lang.ts +0 -0
  87. {dirsql-0.3.5 → dirsql-0.3.7}/docs/guide/persistence.md +0 -0
  88. {dirsql-0.3.5 → dirsql-0.3.7}/docs/migrations.md +0 -0
  89. {dirsql-0.3.5 → dirsql-0.3.7}/docs/package.json +0 -0
  90. {dirsql-0.3.5 → dirsql-0.3.7}/docs/playwright.config.ts +0 -0
  91. {dirsql-0.3.5 → dirsql-0.3.7}/docs/pnpm-lock.yaml +0 -0
  92. {dirsql-0.3.5 → dirsql-0.3.7}/docs/pnpm-workspace.yaml +0 -0
  93. {dirsql-0.3.5 → dirsql-0.3.7}/docs/tests/integration/home.spec.ts +0 -0
  94. {dirsql-0.3.5 → dirsql-0.3.7}/docs/tests/integration/language-flag.spec.ts +0 -0
  95. {dirsql-0.3.5 → dirsql-0.3.7}/docs/tests/unit/lang.test.ts +0 -0
  96. {dirsql-0.3.5 → dirsql-0.3.7}/docs/vitest.config.ts +0 -0
  97. {dirsql-0.3.5 → dirsql-0.3.7}/packages/python/conftest.py +0 -0
  98. {dirsql-0.3.5 → dirsql-0.3.7}/packages/python/docs/.claude/CLAUDE.md +0 -0
  99. {dirsql-0.3.5 → dirsql-0.3.7}/packages/python/docs/.vitepress/theme/index.ts +0 -0
  100. {dirsql-0.3.5 → dirsql-0.3.7}/packages/python/docs/.vitepress/theme/lang.ts +0 -0
  101. {dirsql-0.3.5 → dirsql-0.3.7}/packages/python/docs/guide/persistence.md +0 -0
  102. {dirsql-0.3.5 → dirsql-0.3.7}/packages/python/docs/migrations.md +0 -0
  103. {dirsql-0.3.5 → dirsql-0.3.7}/packages/python/docs/package.json +0 -0
  104. {dirsql-0.3.5 → dirsql-0.3.7}/packages/python/docs/playwright.config.ts +0 -0
  105. {dirsql-0.3.5 → dirsql-0.3.7}/packages/python/docs/pnpm-lock.yaml +0 -0
  106. {dirsql-0.3.5 → dirsql-0.3.7}/packages/python/docs/pnpm-workspace.yaml +0 -0
  107. {dirsql-0.3.5 → dirsql-0.3.7}/packages/python/docs/tests/integration/home.spec.ts +0 -0
  108. {dirsql-0.3.5 → dirsql-0.3.7}/packages/python/docs/tests/integration/language-flag.spec.ts +0 -0
  109. {dirsql-0.3.5 → dirsql-0.3.7}/packages/python/docs/tests/unit/lang.test.ts +0 -0
  110. {dirsql-0.3.5 → dirsql-0.3.7}/packages/python/docs/vitest.config.ts +0 -0
  111. {dirsql-0.3.5 → dirsql-0.3.7}/packages/python/tests/__init__.py +0 -0
  112. {dirsql-0.3.5 → dirsql-0.3.7}/packages/python/tests/conftest.py +0 -0
  113. {dirsql-0.3.5 → dirsql-0.3.7}/packages/python/tests/e2e/__init__.py +0 -0
  114. {dirsql-0.3.5 → dirsql-0.3.7}/packages/python/tests/integration/__init__.py +0 -0
  115. {dirsql-0.3.5 → dirsql-0.3.7}/packages/python/tests/integration/test_binding.py +0 -0
  116. {dirsql-0.3.5 → dirsql-0.3.7}/packages/python/tests/integration/test_from_config.py +0 -0
  117. {dirsql-0.3.5 → dirsql-0.3.7}/packages/rust/benches/db_bench.rs +0 -0
  118. {dirsql-0.3.5 → dirsql-0.3.7}/packages/rust/benches/differ_bench.rs +0 -0
  119. {dirsql-0.3.5 → dirsql-0.3.7}/packages/rust/benches/matcher_bench.rs +0 -0
  120. {dirsql-0.3.5 → dirsql-0.3.7}/packages/rust/benches/scanner_bench.rs +0 -0
  121. {dirsql-0.3.5 → dirsql-0.3.7}/packages/rust/docs/guide/persistence.md +0 -0
  122. {dirsql-0.3.5 → dirsql-0.3.7}/packages/rust/docs/migrations.md +0 -0
  123. {dirsql-0.3.5 → dirsql-0.3.7}/packages/rust/src/cli/init.rs +0 -0
  124. {dirsql-0.3.5 → dirsql-0.3.7}/packages/rust/src/cli/mod.rs +0 -0
  125. {dirsql-0.3.5 → dirsql-0.3.7}/packages/rust/src/cli/router.rs +0 -0
  126. {dirsql-0.3.5 → dirsql-0.3.7}/packages/rust/src/cli/serialize.rs +0 -0
  127. {dirsql-0.3.5 → dirsql-0.3.7}/packages/rust/src/cli/server.rs +0 -0
  128. {dirsql-0.3.5 → dirsql-0.3.7}/packages/rust/src/config.rs +0 -0
  129. {dirsql-0.3.5 → dirsql-0.3.7}/packages/rust/src/db.rs +0 -0
  130. {dirsql-0.3.5 → dirsql-0.3.7}/packages/rust/src/differ.rs +0 -0
  131. {dirsql-0.3.5 → dirsql-0.3.7}/packages/rust/src/matcher.rs +0 -0
  132. {dirsql-0.3.5 → dirsql-0.3.7}/packages/rust/src/scanner.rs +0 -0
  133. {dirsql-0.3.5 → dirsql-0.3.7}/packages/rust/src/watcher.rs +0 -0
  134. {dirsql-0.3.5 → dirsql-0.3.7}/packages/rust/tests/from_config.rs +0 -0
  135. {dirsql-0.3.5 → dirsql-0.3.7}/packages/rust/tests/init_integration.rs +0 -0
@@ -499,7 +499,7 @@ dependencies = [
499
499
 
500
500
  [[package]]
501
501
  name = "dirsql-py-ext"
502
- version = "0.3.5"
502
+ version = "0.3.7"
503
503
  dependencies = [
504
504
  "dirsql",
505
505
  "pyo3",
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: dirsql
3
- Version: 0.3.5
3
+ Version: 0.3.7
4
4
  Requires-Dist: pytest>=8 ; extra == 'dev'
5
5
  Requires-Dist: pytest-describe>=2 ; extra == 'dev'
6
6
  Requires-Dist: pytest-asyncio>=0.23 ; extra == 'dev'
@@ -12,7 +12,7 @@ Summary: Ephemeral SQL index over a local directory
12
12
  Keywords: sql,filesystem,directory,sqlite,index
13
13
  Author: Kevin Scott
14
14
  License-Expression: MIT
15
- Requires-Python: >=3.10
15
+ Requires-Python: >=3.11
16
16
  Description-Content-Type: text/markdown; charset=UTF-8; variant=GFM
17
17
 
18
18
  # `dirsql` (Python SDK)
@@ -64,13 +64,13 @@ async def main():
64
64
  Table(
65
65
  ddl="CREATE TABLE comments (id TEXT, body TEXT, author TEXT)",
66
66
  glob="comments/**/index.jsonl",
67
- extract=lambda path, content: [
67
+ extract=lambda path: [
68
68
  {
69
69
  "id": os.path.basename(os.path.dirname(path)),
70
70
  "body": row["body"],
71
71
  "author": row["author"],
72
72
  }
73
- for line in content.splitlines()
73
+ for line in open(path, encoding="utf-8").read().splitlines()
74
74
  for row in [json.loads(line)]
75
75
  ],
76
76
  ),
@@ -94,12 +94,12 @@ db = DirSQL(
94
94
  Table(
95
95
  ddl="CREATE TABLE posts (title TEXT, author_id TEXT)",
96
96
  glob="posts/*.json",
97
- extract=lambda path, content: [json.loads(content)],
97
+ extract=lambda path: [json.loads(open(path, encoding="utf-8").read())],
98
98
  ),
99
99
  Table(
100
100
  ddl="CREATE TABLE authors (id TEXT, name TEXT)",
101
101
  glob="authors/*.json",
102
- extract=lambda path, content: [json.loads(content)],
102
+ extract=lambda path: [json.loads(open(path, encoding="utf-8").read())],
103
103
  ),
104
104
  ],
105
105
  )
@@ -139,7 +139,7 @@ async def main():
139
139
  Table(
140
140
  ddl="CREATE TABLE items (name TEXT)",
141
141
  glob="**/*.json",
142
- extract=lambda path, content: [json.loads(content)],
142
+ extract=lambda path: [json.loads(open(path, encoding="utf-8").read())],
143
143
  ),
144
144
  ],
145
145
  )
@@ -165,7 +165,7 @@ Defines how files map to a SQL table.
165
165
 
166
166
  - **`ddl`** (`str`): A `CREATE TABLE` statement defining the schema.
167
167
  - **`glob`** (`str`): A glob pattern matched against file paths relative to root.
168
- - **`extract`** (`Callable[[str, str], list[dict]]`): A function receiving `(relative_path, file_content)` and returning a list of row dicts. Each dict's keys must match the DDL column names.
168
+ - **`extract`** (`Callable[[str], list[dict]]`): A function receiving the matched file's absolute filesystem path and returning a list of row dicts. dirsql does not read file contents; a callback that needs the file body reads it itself (e.g. `open(path, encoding="utf-8").read()`). Each dict's keys must match the DDL column names.
169
169
 
170
170
  ### `DirSQL(root=None, *, tables=None, ignore=None, config=None)`
171
171
 
@@ -47,13 +47,13 @@ async def main():
47
47
  Table(
48
48
  ddl="CREATE TABLE comments (id TEXT, body TEXT, author TEXT)",
49
49
  glob="comments/**/index.jsonl",
50
- extract=lambda path, content: [
50
+ extract=lambda path: [
51
51
  {
52
52
  "id": os.path.basename(os.path.dirname(path)),
53
53
  "body": row["body"],
54
54
  "author": row["author"],
55
55
  }
56
- for line in content.splitlines()
56
+ for line in open(path, encoding="utf-8").read().splitlines()
57
57
  for row in [json.loads(line)]
58
58
  ],
59
59
  ),
@@ -77,12 +77,12 @@ db = DirSQL(
77
77
  Table(
78
78
  ddl="CREATE TABLE posts (title TEXT, author_id TEXT)",
79
79
  glob="posts/*.json",
80
- extract=lambda path, content: [json.loads(content)],
80
+ extract=lambda path: [json.loads(open(path, encoding="utf-8").read())],
81
81
  ),
82
82
  Table(
83
83
  ddl="CREATE TABLE authors (id TEXT, name TEXT)",
84
84
  glob="authors/*.json",
85
- extract=lambda path, content: [json.loads(content)],
85
+ extract=lambda path: [json.loads(open(path, encoding="utf-8").read())],
86
86
  ),
87
87
  ],
88
88
  )
@@ -122,7 +122,7 @@ async def main():
122
122
  Table(
123
123
  ddl="CREATE TABLE items (name TEXT)",
124
124
  glob="**/*.json",
125
- extract=lambda path, content: [json.loads(content)],
125
+ extract=lambda path: [json.loads(open(path, encoding="utf-8").read())],
126
126
  ),
127
127
  ],
128
128
  )
@@ -148,7 +148,7 @@ Defines how files map to a SQL table.
148
148
 
149
149
  - **`ddl`** (`str`): A `CREATE TABLE` statement defining the schema.
150
150
  - **`glob`** (`str`): A glob pattern matched against file paths relative to root.
151
- - **`extract`** (`Callable[[str, str], list[dict]]`): A function receiving `(relative_path, file_content)` and returning a list of row dicts. Each dict's keys must match the DDL column names.
151
+ - **`extract`** (`Callable[[str], list[dict]]`): A function receiving the matched file's absolute filesystem path and returning a list of row dicts. dirsql does not read file contents; a callback that needs the file body reads it itself (e.g. `open(path, encoding="utf-8").read()`). Each dict's keys must match the DDL column names.
152
152
 
153
153
  ### `DirSQL(root=None, *, tables=None, ignore=None, config=None)`
154
154
 
@@ -0,0 +1,83 @@
1
+ import { defineConfig } from 'vitepress'
2
+
3
+ export default defineConfig({
4
+ title: 'dirsql',
5
+ description: 'Ephemeral SQL index over a local directory. Watches a filesystem, ingests structured files into an in-memory SQLite database, and exposes a SQL query interface.',
6
+ base: '/dirsql/',
7
+
8
+ themeConfig: {
9
+ search: {
10
+ provider: 'local'
11
+ },
12
+
13
+ nav: [
14
+ { text: 'Getting Started', link: '/getting-started' },
15
+ { text: 'Guide', link: '/guide/tables' },
16
+ { text: 'CLI', link: '/cli/' },
17
+ { text: 'Reference', link: '/api/' },
18
+ { text: 'Migrations', link: '/migrations' },
19
+ { text: 'GitHub', link: 'https://github.com/thekevinscott/dirsql' }
20
+ ],
21
+
22
+ sidebar: {
23
+ '/cli/': [
24
+ {
25
+ text: 'CLI',
26
+ items: [
27
+ { text: 'Overview & Installation', link: '/cli/' },
28
+ { text: 'Running the Server', link: '/cli/server' },
29
+ { text: 'Generating a Config (`init`)', link: '/cli/init' },
30
+ { text: 'Configuration File', link: '/cli/config' },
31
+ { text: 'HTTP API', link: '/cli/http-api' }
32
+ ]
33
+ }
34
+ ],
35
+ '/': [
36
+ {
37
+ text: 'Tutorials',
38
+ items: [
39
+ { text: 'Getting Started', link: '/getting-started' }
40
+ ]
41
+ },
42
+ {
43
+ text: 'How-to Guides',
44
+ items: [
45
+ { text: 'Defining Tables', link: '/guide/tables' },
46
+ { text: 'Querying', link: '/guide/querying' },
47
+ { text: 'File Watching', link: '/guide/watching' },
48
+ { text: 'Persistence', link: '/guide/persistence' },
49
+ { text: 'Async API', link: '/guide/async' },
50
+ { text: 'Collaboration with CRDTs', link: '/guide/crdt' }
51
+ ]
52
+ },
53
+ {
54
+ text: 'CLI',
55
+ items: [
56
+ { text: 'Using `dirsql` from the CLI', link: '/cli/' }
57
+ ]
58
+ },
59
+ {
60
+ text: 'Reference',
61
+ items: [
62
+ { text: 'API Reference', link: '/api/' },
63
+ { text: 'Migrations', link: '/migrations' }
64
+ ]
65
+ }
66
+ ]
67
+ },
68
+
69
+ outline: {
70
+ level: [2, 3],
71
+ label: 'On this page'
72
+ },
73
+
74
+ socialLinks: [
75
+ { icon: 'github', link: 'https://github.com/thekevinscott/dirsql' }
76
+ ],
77
+
78
+ footer: {
79
+ message: 'Released under the MIT License.',
80
+ copyright: 'Copyright 2024-present'
81
+ }
82
+ }
83
+ })
@@ -42,6 +42,12 @@ The docs follow the [Diataxis](https://diataxis.fr/) framework:
42
42
  - **Reference** (`api/`) -- information-oriented, API details
43
43
  - **Explanation** (`architecture.md`) -- understanding-oriented, design decisions
44
44
 
45
+ The **CLI** (`cli/`) is a self-contained section reachable from its own
46
+ top-level `CLI` nav tab, with a path-scoped sidebar (`/cli/` key in
47
+ `config.ts`). Everything a CLI user needs -- installation, running the server,
48
+ `init`, the `.dirsql.toml` config file, and the HTTP API -- lives under
49
+ `cli/`. Do not move CLI pages back into `guide/`.
50
+
45
51
  ## Conventions
46
52
 
47
53
  - Wrap `dirsql` in backticks in all prose text
@@ -168,15 +168,15 @@ import { Table } from 'dirsql';
168
168
  ::: code-group
169
169
 
170
170
  ```python [Python]
171
- Table(*, ddl: str, glob: str, extract: Callable[[str, str], list[dict]])
171
+ Table(*, ddl: str, glob: str, extract: Callable[[str], list[dict]])
172
172
  ```
173
173
 
174
174
  ```rust [Rust]
175
- Table::new(ddl: &str, glob: &str, extract: fn(&str, &str) -> Vec<Value>)
175
+ Table::new(ddl: &str, glob: &str, extract: fn(&str) -> Vec<Value>)
176
176
  ```
177
177
 
178
178
  ```typescript [TypeScript]
179
- new Table({ ddl: string, glob: string, extract: (path: string, content: string) => Record<string, unknown>[] })
179
+ new Table({ ddl: string, glob: string, extract: (path: string) => Record<string, unknown>[] })
180
180
  ```
181
181
 
182
182
  :::
@@ -187,7 +187,7 @@ Defines a mapping from files to SQLite table rows.
187
187
 
188
188
  - `ddl` -- A `CREATE TABLE` statement. The table name is parsed from this DDL.
189
189
  - `glob` -- A glob pattern matched against file paths relative to the root directory.
190
- - `extract` -- A callable `(path, content) -> list[dict]`. Receives the relative file path and file content as strings. Returns a list of dicts/maps mapping column names to values. Return an empty list to skip a file.
190
+ - `extract` -- A callable `(path) -> list[dict]`. Receives the absolute filesystem path of the matched file. `dirsql` does not read file contents; a callback that needs the file body reads `path` itself. Returns a list of dicts/maps mapping column names to values. Return an empty list to skip a file.
191
191
 
192
192
  **Attributes:**
193
193
 
@@ -1,23 +1,12 @@
1
1
  ---
2
- canonical: https://thekevinscott.github.io/dirsql/guide/config
2
+ canonical: https://thekevinscott.github.io/dirsql/cli/config
3
3
  ---
4
4
 
5
5
  # Configuration File
6
6
 
7
- > Online: <https://thekevinscott.github.io/dirsql/guide/config>
7
+ > Online: <https://thekevinscott.github.io/dirsql/cli/config>
8
8
 
9
- `dirsql` can be configured with a `.dirsql.toml` file. Tables defined this
10
- way produce **one row per matched file**. Each row's columns come from
11
- filesystem facts:
12
-
13
- - **Glob path captures** — named `{placeholder}` segments in the glob.
14
- - **Stat virtuals** — reserved `_`-prefixed columns for path-derived and
15
- stat-derived metadata.
16
-
17
- Content interpretation (parsing JSON, CSV, frontmatter, etc.) is **not**
18
- configured in `.dirsql.toml`. If you need columns derived from file
19
- contents, register a programmatic [`Table`](./tables.md) whose `extract`
20
- function does the parsing in your host language.
9
+ `dirsql` can be configured with an optional `.dirsql.toml` file (if omitted, server falls back to [defaults](./server.md#defaults)). `.dirsql.toml` defines how files are parsed into SQL tables.
21
10
 
22
11
  ## Basic Example
23
12
 
@@ -30,8 +19,7 @@ ddl = "CREATE TABLE posts (_path TEXT, _basename TEXT, _size INTEGER, _mtime IN
30
19
  glob = "posts/*.md"
31
20
  ```
32
21
 
33
- Each `posts/*.md` file produces one row. The DDL declares which stat
34
- virtuals are surfaced as SQL columns.
22
+ Each `posts/*.md` file produces one row in the `posts` table.
35
23
 
36
24
  ## Loading a Config File
37
25
 
@@ -131,7 +119,7 @@ ignore = ["node_modules/**", ".git/**", "*.pyc", "__pycache__/**"]
131
119
 
132
120
  The top-level `.dirsql/` directory is always excluded, whether you list it
133
121
  or not — it is a reserved namespace for `dirsql`'s own metadata (see
134
- [Persistence](./persistence.md)).
122
+ [Persistence](../guide/persistence.md)).
135
123
 
136
124
  ## Persistence
137
125
 
@@ -144,7 +132,7 @@ persist = true
144
132
  # persist_path = ".dirsql/cache.db" # optional; this is the default
145
133
  ```
146
134
 
147
- See [Persistence](./persistence.md) for the full reconcile algorithm,
135
+ See [Persistence](../guide/persistence.md) for the full reconcile algorithm,
148
136
  storage layout, and limitations.
149
137
 
150
138
  ## Strict Mode
@@ -163,7 +151,7 @@ strict = true
163
151
  Strict mode does **not** apply to auto-injected stat virtuals — those are
164
152
  always filtered to the DDL's declared columns regardless. Strict mode
165
153
  applies only to keys produced by an extract callback (relevant for
166
- programmatic [tables](./tables.md)).
154
+ programmatic [tables](../guide/tables.md)).
167
155
 
168
156
  ## Full Example
169
157
 
@@ -188,6 +176,6 @@ glob = "logs/*.csv"
188
176
 
189
177
  `.dirsql.toml` does not parse file contents. For columns derived from the
190
178
  *inside* of files (frontmatter keys, JSON values, CSV cells, etc.),
191
- register a programmatic [`Table`](./tables.md) instead, and parse the
179
+ register a programmatic [`Table`](../guide/tables.md) instead, and parse the
192
180
  bytes in your host language. Glob captures and stat virtuals are still
193
181
  auto-injected into rows produced by your extract.
@@ -1,65 +1,16 @@
1
1
  ---
2
- canonical: https://thekevinscott.github.io/dirsql/guide/cli
2
+ canonical: https://thekevinscott.github.io/dirsql/cli/http-api
3
3
  ---
4
4
 
5
- # Command-Line Interface
5
+ # HTTP API
6
6
 
7
- > Online: <https://thekevinscott.github.io/dirsql/guide/cli>
7
+ > Online: <https://thekevinscott.github.io/dirsql/cli/http-api>
8
8
 
9
- `dirsql` starts an HTTP server that exposes identical SDK functionality.
9
+ Once the [server is running](./server.md), `dirsql` exposes two HTTP
10
+ endpoints: `POST /query` for SQL queries and `GET /events` for a real-time
11
+ change stream.
10
12
 
11
- ## Installation
12
-
13
- ::: code-group
14
-
15
- ```bash [npm]
16
- npx dirsql
17
- ```
18
-
19
- ```bash [PyPI]
20
- uvx dirsql
21
- ```
22
-
23
- ```bash [Cargo]
24
- # Installs the binary only (non-default feature)
25
- cargo install dirsql --features cli
26
- dirsql
27
- ```
28
-
29
- :::
30
-
31
- ::: tip For Rust library consumers
32
- The `cli` feature is **opt-in**. Adding `dirsql` as a library dependency (`cargo add dirsql`) pulls no CLI dependencies — only the core library. See the [Rust library README](https://github.com/thekevinscott/dirsql/tree/main/packages/rust) for details.
33
- :::
34
-
35
- ## Subcommands
36
-
37
- | Command | Purpose |
38
- |---|---|
39
- | `dirsql` (no subcommand) | Start the long-lived HTTP server (default behavior, see below). |
40
- | `dirsql init` | Generate a starter `.dirsql.toml` from the contents of a directory. See [Generating a Config](./init.md). |
41
-
42
- ## Running the server
43
-
44
- Run `dirsql` from the directory containing your files:
45
-
46
- ```bash
47
- dirsql
48
-
49
- $ Running at localhost:7117
50
- ```
51
-
52
- ### Flags
53
-
54
- | Flag | Default | Description |
55
- |---|---|---|
56
- | `--config <path>` | `./.dirsql.toml` | Path to the config file. The index is rooted at the directory containing this file. |
57
- | `--host <addr>` | `localhost` | Bind address |
58
- | `--port <n>` | `7117` | TCP port to bind |
59
-
60
- ## HTTP API
61
-
62
- ### `POST /query`
13
+ ## `POST /query`
63
14
 
64
15
  Run a SQL query. Request body is JSON:
65
16
 
@@ -91,9 +42,12 @@ curl -s http://localhost:7117/query \
91
42
  | jq
92
43
  ```
93
44
 
94
- ### `GET /events`
45
+ The query interface is the same one the SDK exposes; see [Querying](../guide/querying.md)
46
+ for SQL semantics, the read-only restriction, and the return format.
47
+
48
+ ## `GET /events`
95
49
 
96
- Opens a [Server-Sent Events](https://developer.mozilla.org/en-US/docs/Web/API/Server-sent_events) stream of change events. Each `data:` payload is the same JSON schema the SDK emits from [`db.watch()`](./watching.md#event-types):
50
+ Opens a [Server-Sent Events](https://developer.mozilla.org/en-US/docs/Web/API/Server-sent_events) stream of change events. Each `data:` payload is the same JSON schema the SDK emits from [`db.watch()`](../guide/watching.md#event-types):
97
51
 
98
52
  ```
99
53
  event: row
@@ -0,0 +1,73 @@
1
+ ---
2
+ canonical: https://thekevinscott.github.io/dirsql/cli/
3
+ ---
4
+
5
+ # Using `dirsql` from the CLI
6
+
7
+ > Online: <https://thekevinscott.github.io/dirsql/cli/>
8
+
9
+ `dirsql` ships a command-line interface that starts an HTTP server exposing
10
+ the same indexing, querying, and watching functionality as the SDK — no host
11
+ language required. Run it in any directory to query your files over HTTP:
12
+ with no config it serves a default `files` table, and a
13
+ [`.dirsql.toml`](./config.md) config defines custom tables.
14
+
15
+ Everything you need to run `dirsql` as a CLI lives in this section:
16
+
17
+ - **[Installation](#installation)** — get the `dirsql` binary.
18
+ - **[Running the Server](./server.md)** — subcommands and flags.
19
+ - **[Generating a Config (`init`)](./init.md)** — scaffold a `.dirsql.toml`.
20
+ - **[Configuration File](./config.md)** — the `.dirsql.toml` format. Custom
21
+ tables are defined exclusively through this file; without it, the server
22
+ runs in [zero-config mode](./server.md#zero-config-mode).
23
+ - **[HTTP API](./http-api.md)** — the `POST /query` and `GET /events`
24
+ endpoints, status codes, and event streaming.
25
+
26
+ ## Installation
27
+
28
+ ::: code-group
29
+
30
+ ```bash [npm]
31
+ npx dirsql
32
+ ```
33
+
34
+ ```bash [PyPI]
35
+ uvx dirsql
36
+ ```
37
+
38
+ ```bash [Cargo]
39
+ # Installs the binary only (the `cli` feature is non-default)
40
+ cargo install dirsql --features cli
41
+ dirsql
42
+ ```
43
+
44
+ :::
45
+
46
+ ::: tip For Rust library consumers
47
+ The `cli` feature is **opt-in**. Adding `dirsql` as a library dependency
48
+ (`cargo add dirsql`) pulls no CLI dependencies — only the core library. See the
49
+ [Rust library README](https://github.com/thekevinscott/dirsql/tree/main/packages/rust)
50
+ for the library-vs-CLI feature split.
51
+ :::
52
+
53
+ ## Quick start
54
+
55
+ From a directory containing your files and a [`.dirsql.toml`](./config.md):
56
+
57
+ ```bash
58
+ dirsql
59
+
60
+ $ Running at localhost:7117
61
+ ```
62
+
63
+ Then query it over HTTP:
64
+
65
+ ```bash
66
+ curl -s http://localhost:7117/query \
67
+ -H 'content-type: application/json' \
68
+ -d '{"sql":"SELECT COUNT(*) AS n FROM posts"}' \
69
+ | jq
70
+ ```
71
+
72
+ See [Running the Server](./server.md) for flags and [HTTP API](./http-api.md)
73
+ for the full endpoint reference.
@@ -1,14 +1,14 @@
1
1
  ---
2
- canonical: https://thekevinscott.github.io/dirsql/guide/init
2
+ canonical: https://thekevinscott.github.io/dirsql/cli/init
3
3
  ---
4
4
 
5
5
  # Generating a config with `dirsql init`
6
6
 
7
- > Online: <https://thekevinscott.github.io/dirsql/guide/init>
7
+ > Online: <https://thekevinscott.github.io/dirsql/cli/init>
8
8
 
9
- `dirsql init` generates a `.dirsql.toml` by running `claude` over the target directory.
9
+ `dirsql init` generates a [`.dirsql.toml`](./config.md) by running `claude` over the target directory.
10
10
 
11
- The output is limited to filesystem-fact tables. For content-aware schemas, see [Defining Tables](./tables.md).
11
+ The output is limited to filesystem-fact tables. For content-aware schemas, see [Defining Tables](../guide/tables.md).
12
12
 
13
13
  ## Examples
14
14
 
@@ -0,0 +1,59 @@
1
+ ---
2
+ canonical: https://thekevinscott.github.io/dirsql/cli/server
3
+ ---
4
+
5
+ # Running the Server
6
+
7
+ > Online: <https://thekevinscott.github.io/dirsql/cli/server>
8
+
9
+ The `dirsql` CLI is an HTTP server that exposes identical SDK functionality
10
+ over [`POST /query`](./http-api.md#post-query) and [`GET /events`](./http-api.md#get-events).
11
+
12
+ ## Subcommands
13
+
14
+ | Command | Purpose |
15
+ |---|---|
16
+ | `dirsql` (no subcommand) | Start the long-lived HTTP server (default behavior, see below). |
17
+ | `dirsql init` | Generate a starter `.dirsql.toml` from the contents of a directory. See [Generating a Config](./init.md). |
18
+
19
+ ## Running the server
20
+
21
+ Run `dirsql` from the directory containing your files:
22
+
23
+ ```bash
24
+ dirsql
25
+
26
+ $ Running at localhost:7117
27
+ ```
28
+
29
+ The server reads tables from a [`.dirsql.toml`](./config.md) config file. By
30
+ default it looks for `./.dirsql.toml`; override the path with `--config`.
31
+
32
+ ## Defaults
33
+
34
+ If no config file is found, `dirsql` serves a single table named `files`, with one row per file under the directory
35
+
36
+ ```bash
37
+ cd ~/some/directory # no .dirsql.toml here
38
+ dirsql
39
+
40
+ $ Running at localhost:7117
41
+ ```
42
+
43
+ ```bash
44
+ curl -s localhost:7117/query -H 'content-type: application/json' \
45
+ -d '{"sql":"SELECT _basename, _size FROM files ORDER BY _size DESC LIMIT 5"}'
46
+ ```
47
+
48
+ A `.dirsql.toml` file will override the default.
49
+
50
+ ## Flags
51
+
52
+ | Flag | Default | Description |
53
+ |---|---|---|
54
+ | `--config <path>` | `./.dirsql.toml` | Path to the config file. The index is rooted at the directory containing this file. |
55
+ | `--host <addr>` | `localhost` | Bind address |
56
+ | `--port <n>` | `7117` | TCP port to bind |
57
+
58
+ Once the server is running, see the [HTTP API](./http-api.md) for the request
59
+ and response formats.
@@ -31,7 +31,7 @@ cargo install dirsql --features cli
31
31
 
32
32
  :::
33
33
 
34
- See the [CLI guide](./guide/cli.md) for details on the command-line interface, and the [Rust library README](https://github.com/thekevinscott/dirsql/tree/main/packages/rust) for the library-vs-CLI feature split.
34
+ See the [CLI section](./cli/) for details on the command-line interface, and the [Rust library README](https://github.com/thekevinscott/dirsql/tree/main/packages/rust) for the library-vs-CLI feature split.
35
35
 
36
36
  ## Quick start
37
37
 
@@ -63,12 +63,12 @@ async def main():
63
63
  Table(
64
64
  ddl="CREATE TABLE posts (title TEXT, author TEXT)",
65
65
  glob="posts/*.json",
66
- extract=lambda path, content: [json.loads(content)],
66
+ extract=lambda path: [json.loads(open(path, encoding="utf-8").read())],
67
67
  ),
68
68
  Table(
69
69
  ddl="CREATE TABLE authors (id TEXT, name TEXT)",
70
70
  glob="authors/*.json",
71
- extract=lambda path, content: [json.loads(content)],
71
+ extract=lambda path: [json.loads(open(path, encoding="utf-8").read())],
72
72
  ),
73
73
  ],
74
74
  )
@@ -120,12 +120,12 @@ let db = DirSQL::new(
120
120
  Table::new(
121
121
  "CREATE TABLE posts (title TEXT, author TEXT)",
122
122
  "posts/*.json",
123
- |_path, content| vec![row_from_json(content)],
123
+ |path| vec![row_from_json(&std::fs::read_to_string(path).unwrap())],
124
124
  ),
125
125
  Table::new(
126
126
  "CREATE TABLE authors (id TEXT, name TEXT)",
127
127
  "authors/*.json",
128
- |_path, content| vec![row_from_json(content)],
128
+ |path| vec![row_from_json(&std::fs::read_to_string(path).unwrap())],
129
129
  ),
130
130
  ],
131
131
  )?;
@@ -139,18 +139,19 @@ let results = db.query(
139
139
  ```
140
140
 
141
141
  ```typescript [TypeScript]
142
+ import { readFileSync } from 'node:fs';
142
143
  import { DirSQL, type TableDef } from 'dirsql';
143
144
 
144
145
  const tables: TableDef[] = [
145
146
  {
146
147
  ddl: 'CREATE TABLE posts (title TEXT, author TEXT)',
147
148
  glob: 'posts/*.json',
148
- extract: (_path, content) => [JSON.parse(content)],
149
+ extract: (path) => [JSON.parse(readFileSync(path, 'utf8'))],
149
150
  },
150
151
  {
151
152
  ddl: 'CREATE TABLE authors (id TEXT, name TEXT)',
152
153
  glob: 'authors/*.json',
153
- extract: (_path, content) => [JSON.parse(content)],
154
+ extract: (path) => [JSON.parse(readFileSync(path, 'utf8'))],
154
155
  },
155
156
  ];
156
157
 
@@ -169,8 +170,8 @@ const results = await db.query(`
169
170
  ## What happens at startup
170
171
 
171
172
  1. `dirsql` walks the directory tree
172
- 2. Files matching each table's glob pattern are read
173
- 3. The `extract` function converts file content into rows
173
+ 2. Files matching each table's glob pattern are identified
174
+ 3. The `extract` function receives each matched file's absolute path and returns rows
174
175
  4. Rows are inserted into an in-memory SQLite database
175
176
  5. SQL queries run against that database
176
177
 
@@ -182,5 +183,5 @@ The filesystem is always the source of truth. The database is rebuilt from files
182
183
  - [Querying](./guide/querying.md) -- SQL queries and return format
183
184
  - [File Watching](./guide/watching.md) -- real-time change events
184
185
  - [Async API](./guide/async.md) -- async ready(), query(), and watch()
185
- - [Command-Line Interface](./guide/cli.md) -- `dirsql` runs an HTTP server (`POST /query`, `GET /events` SSE)
186
+ - [Using `dirsql` from the CLI](./cli/) -- `dirsql` runs an HTTP server (`POST /query`, `GET /events` SSE)
186
187
  - [Collaboration with CRDTs](./guide/crdt.md) -- multi-writer document merging alongside `dirsql`