meadow 2.0.23 → 2.0.27

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 (62) hide show
  1. package/README.md +110 -141
  2. package/docs/README.md +34 -230
  3. package/docs/_cover.md +14 -0
  4. package/docs/_sidebar.md +44 -12
  5. package/docs/_topbar.md +5 -0
  6. package/docs/api/doCount.md +109 -0
  7. package/docs/api/doCreate.md +132 -0
  8. package/docs/api/doDelete.md +101 -0
  9. package/docs/api/doRead.md +122 -0
  10. package/docs/api/doReads.md +136 -0
  11. package/docs/api/doUndelete.md +98 -0
  12. package/docs/api/doUpdate.md +129 -0
  13. package/docs/api/getRoleName.md +84 -0
  14. package/docs/api/loadFromPackage.md +153 -0
  15. package/docs/api/marshalRecordFromSourceToObject.md +92 -0
  16. package/docs/api/query.md +133 -0
  17. package/docs/api/rawQueries.md +197 -0
  18. package/docs/api/reference.md +117 -0
  19. package/docs/api/setAuthorizer.md +103 -0
  20. package/docs/api/setDefault.md +90 -0
  21. package/docs/api/setDefaultIdentifier.md +84 -0
  22. package/docs/api/setDomain.md +56 -0
  23. package/docs/api/setIDUser.md +91 -0
  24. package/docs/api/setJsonSchema.md +92 -0
  25. package/docs/api/setProvider.md +87 -0
  26. package/docs/api/setSchema.md +107 -0
  27. package/docs/api/setScope.md +68 -0
  28. package/docs/api/validateObject.md +119 -0
  29. package/docs/architecture.md +316 -0
  30. package/docs/audit-tracking.md +226 -0
  31. package/docs/configuration.md +317 -0
  32. package/docs/providers/meadow-endpoints.md +306 -0
  33. package/docs/providers/mongodb.md +319 -0
  34. package/docs/providers/postgresql.md +312 -0
  35. package/docs/providers/rocksdb.md +297 -0
  36. package/docs/query-dsl.md +269 -0
  37. package/docs/quick-start.md +384 -0
  38. package/docs/raw-queries.md +193 -0
  39. package/docs/retold-catalog.json +61 -1
  40. package/docs/retold-keyword-index.json +15860 -4839
  41. package/docs/soft-deletes.md +224 -0
  42. package/package.json +44 -13
  43. package/scripts/bookstore-seed-postgresql.sql +135 -0
  44. package/scripts/dgraph-test-db.sh +144 -0
  45. package/scripts/meadow-test-cleanup.sh +5 -1
  46. package/scripts/mongodb-test-db.sh +98 -0
  47. package/scripts/postgresql-test-db.sh +124 -0
  48. package/scripts/solr-test-db.sh +135 -0
  49. package/source/Meadow.js +5 -0
  50. package/source/providers/Meadow-Provider-DGraph.js +679 -0
  51. package/source/providers/Meadow-Provider-MeadowEndpoints.js +1 -1
  52. package/source/providers/Meadow-Provider-MongoDB.js +527 -0
  53. package/source/providers/Meadow-Provider-PostgreSQL.js +361 -0
  54. package/source/providers/Meadow-Provider-RocksDB.js +1300 -0
  55. package/source/providers/Meadow-Provider-Solr.js +726 -0
  56. package/test/Meadow-Provider-DGraph_tests.js +741 -0
  57. package/test/Meadow-Provider-MongoDB_tests.js +661 -0
  58. package/test/Meadow-Provider-PostgreSQL_tests.js +787 -0
  59. package/test/Meadow-Provider-RocksDB_tests.js +887 -0
  60. package/test/Meadow-Provider-SQLiteBrowser-Headless_tests.js +657 -0
  61. package/test/Meadow-Provider-SQLiteBrowser_tests.js +895 -0
  62. package/test/Meadow-Provider-Solr_tests.js +679 -0
@@ -0,0 +1,317 @@
1
+ # Configuration
2
+
3
+ Meadow is configured through the Fable settings object. All settings are passed when constructing the Fable instance and are available to Meadow and its providers at runtime.
4
+
5
+ ## Core Meadow Settings
6
+
7
+ ### MeadowProvider
8
+
9
+ The name of the database provider to use by default when creating new Meadow instances.
10
+
11
+ - **Type:** `String`
12
+ - **Default:** `'None'`
13
+ - **Valid values:** `'MySQL'`, `'MSSQL'`, `'PostgreSQL'`, `'SQLite'`, `'MongoDB'`, `'RocksDB'`, `'ALASQL'`, `'MeadowEndpoints'`, `'None'`
14
+
15
+ ```javascript
16
+ var _Fable = new libFable(
17
+ {
18
+ MeadowProvider: 'MySQL'
19
+ });
20
+ ```
21
+
22
+ When set, every `libMeadow.new(_Fable, 'SomeEntity')` call automatically uses this provider. You can override it per-DAL with `meadow.setProvider('OtherProvider')`.
23
+
24
+ ### MeadowRoleNames
25
+
26
+ An ordered array of role names used by the authorization system. Role indices map to positions in this array.
27
+
28
+ - **Type:** `Array<String>`
29
+ - **Default:**
30
+ ```javascript
31
+ [
32
+ 'Unauthenticated',
33
+ 'User',
34
+ 'Manager',
35
+ 'Director',
36
+ 'Executive',
37
+ 'Administrator'
38
+ ]
39
+ ```
40
+
41
+ ```javascript
42
+ var _Fable = new libFable(
43
+ {
44
+ MeadowRoleNames:
45
+ [
46
+ 'Anonymous',
47
+ 'Viewer',
48
+ 'Editor',
49
+ 'Admin',
50
+ 'SuperAdmin'
51
+ ]
52
+ });
53
+ ```
54
+
55
+ Role names are retrieved with `meadow.getRoleName(pRoleIndex)`. If the index is out of bounds, `'Unauthenticated'` (or your first role name) is returned.
56
+
57
+ ### QueryThresholdWarnTime
58
+
59
+ The threshold in milliseconds for slow query warnings. When a `doReads` or `doCount` operation exceeds this time, Meadow logs a warning with the full query details.
60
+
61
+ - **Type:** `Number`
62
+ - **Default:** `200`
63
+ - **Unit:** milliseconds
64
+
65
+ ```javascript
66
+ var _Fable = new libFable(
67
+ {
68
+ QueryThresholdWarnTime: 500
69
+ });
70
+ ```
71
+
72
+ ## MySQL Connection Settings
73
+
74
+ The `MySQL` settings object configures the MySQL provider and connection pool.
75
+
76
+ | Setting | Type | Default | Description |
77
+ |---------|------|---------|-------------|
78
+ | `Server` | `String` | `'localhost'` | Database server hostname |
79
+ | `Port` | `Number` | `3306` | Database server port |
80
+ | `User` | `String` | `'root'` | Database user |
81
+ | `Password` | `String` | `''` | Database password |
82
+ | `Database` | `String` | `''` | Database name |
83
+ | `ConnectionPoolLimit` | `Number` | `20` | Maximum connections in the pool |
84
+ | `GlobalLogLevel` | `Number` | `0` | Set to `> 0` to trace all query bodies |
85
+
86
+ ```javascript
87
+ var _Fable = new libFable(
88
+ {
89
+ MeadowProvider: 'MySQL',
90
+ MySQL:
91
+ {
92
+ Server: 'db.example.com',
93
+ Port: 3306,
94
+ User: 'app_user',
95
+ Password: 'secret',
96
+ Database: 'my_application',
97
+ ConnectionPoolLimit: 20,
98
+ GlobalLogLevel: 0
99
+ }
100
+ });
101
+ ```
102
+
103
+ ## MSSQL Connection Settings
104
+
105
+ The `MSSQL` settings object configures the Microsoft SQL Server provider. The connection pool is managed by the `meadow-connection-mssql` module.
106
+
107
+ | Setting | Type | Default | Description |
108
+ |---------|------|---------|-------------|
109
+ | `Server` | `String` | `'localhost'` | Database server hostname |
110
+ | `Port` | `Number` | `1433` | Database server port |
111
+ | `User` | `String` | `'sa'` | Database user |
112
+ | `Password` | `String` | `''` | Database password |
113
+ | `Database` | `String` | `''` | Database name |
114
+ | `ConnectionPoolLimit` | `Number` | `20` | Maximum connections in the pool |
115
+ | `GlobalLogLevel` | `Number` | `0` | Set to `> 0` to trace all query bodies |
116
+
117
+ ```javascript
118
+ var _Fable = new libFable(
119
+ {
120
+ MeadowProvider: 'MSSQL',
121
+ MSSQL:
122
+ {
123
+ Server: 'sqlserver.example.com',
124
+ Port: 1433,
125
+ User: 'sa',
126
+ Password: 'secret',
127
+ Database: 'my_application',
128
+ ConnectionPoolLimit: 20,
129
+ GlobalLogLevel: 0
130
+ }
131
+ });
132
+ ```
133
+
134
+ ## PostgreSQL Connection Settings
135
+
136
+ The `PostgreSQL` settings object configures the PostgreSQL provider.
137
+
138
+ | Setting | Type | Default | Description |
139
+ |---------|------|---------|-------------|
140
+ | `Server` | `String` | `'localhost'` | Database server hostname |
141
+ | `Port` | `Number` | `5432` | Database server port |
142
+ | `User` | `String` | `'postgres'` | Database user |
143
+ | `Password` | `String` | `''` | Database password |
144
+ | `Database` | `String` | `''` | Database name |
145
+ | `GlobalLogLevel` | `Number` | `0` | Set to `> 0` to trace all query bodies |
146
+
147
+ ```javascript
148
+ var _Fable = new libFable(
149
+ {
150
+ MeadowProvider: 'PostgreSQL',
151
+ PostgreSQL:
152
+ {
153
+ Server: 'pg.example.com',
154
+ Port: 5432,
155
+ User: 'postgres',
156
+ Password: 'secret',
157
+ Database: 'my_application',
158
+ GlobalLogLevel: 0
159
+ }
160
+ });
161
+ ```
162
+
163
+ ## MeadowEndpoints Settings
164
+
165
+ The `MeadowEndpoints` settings object configures the REST API proxy provider. This provider translates CRUD operations into HTTP requests against a remote Meadow-Endpoints server.
166
+
167
+ | Setting | Type | Default | Description |
168
+ |---------|------|---------|-------------|
169
+ | `ServerProtocol` | `String` | `'http'` | Protocol (`'http'` or `'https'`) |
170
+ | `ServerAddress` | `String` | `'127.0.0.1'` | Remote server hostname |
171
+ | `ServerPort` | `String` | `'8086'` | Remote server port |
172
+ | `ServerEndpointPrefix` | `String` | `'1.0/'` | URL prefix for API endpoints |
173
+
174
+ ```javascript
175
+ var _Fable = new libFable(
176
+ {
177
+ MeadowProvider: 'MeadowEndpoints',
178
+ MeadowEndpoints:
179
+ {
180
+ ServerProtocol: 'https',
181
+ ServerAddress: 'api.example.com',
182
+ ServerPort: '443',
183
+ ServerEndpointPrefix: '1.0/'
184
+ }
185
+ });
186
+ ```
187
+
188
+ ## SQLite Settings
189
+
190
+ SQLite is configured through the `meadow-connection-sqlite` connection module. The connection provider manages the `better-sqlite3` database instance.
191
+
192
+ ```javascript
193
+ var _Fable = new libFable(
194
+ {
195
+ MeadowProvider: 'SQLite'
196
+ });
197
+
198
+ var libMeadowConnectionSQLite = require('meadow-connection-sqlite');
199
+ var tmpConnection = libMeadowConnectionSQLite.new(_Fable);
200
+ tmpConnection.connectAsync(':memory:');
201
+ ```
202
+
203
+ SQLite supports both file-based databases (pass a file path) and in-memory databases (pass `':memory:'`).
204
+
205
+ ## MongoDB Settings
206
+
207
+ The `MongoDB` settings object configures the MongoDB provider.
208
+
209
+ | Setting | Type | Default | Description |
210
+ |---------|------|---------|-------------|
211
+ | `URL` | `String` | `''` | MongoDB connection URL |
212
+ | `Database` | `String` | `''` | Database name |
213
+ | `GlobalLogLevel` | `Number` | `0` | Set to `> 0` to trace all query bodies |
214
+
215
+ ```javascript
216
+ var _Fable = new libFable(
217
+ {
218
+ MeadowProvider: 'MongoDB',
219
+ MongoDB:
220
+ {
221
+ URL: 'mongodb://localhost:27017',
222
+ Database: 'my_application',
223
+ GlobalLogLevel: 0
224
+ }
225
+ });
226
+ ```
227
+
228
+ ## RocksDB Settings
229
+
230
+ The `RocksDB` settings object configures the RocksDB key-value provider.
231
+
232
+ | Setting | Type | Default | Description |
233
+ |---------|------|---------|-------------|
234
+ | `KeyMode` | `String` | `'GUID'` | Key strategy: `'GUID'` or `'ID'` |
235
+ | `GlobalLogLevel` | `Number` | `0` | Set to `> 0` to trace all operations |
236
+
237
+ ```javascript
238
+ var _Fable = new libFable(
239
+ {
240
+ MeadowProvider: 'RocksDB',
241
+ RocksDB:
242
+ {
243
+ KeyMode: 'GUID',
244
+ GlobalLogLevel: 0
245
+ }
246
+ });
247
+ ```
248
+
249
+ ## Full Example
250
+
251
+ A complete Fable settings object showing all available Meadow options:
252
+
253
+ ```json
254
+ {
255
+ "MeadowProvider": "MySQL",
256
+
257
+ "MeadowRoleNames": [
258
+ "Unauthenticated",
259
+ "User",
260
+ "Manager",
261
+ "Director",
262
+ "Executive",
263
+ "Administrator"
264
+ ],
265
+
266
+ "QueryThresholdWarnTime": 200,
267
+
268
+ "MySQL": {
269
+ "Server": "localhost",
270
+ "Port": 3306,
271
+ "User": "app_user",
272
+ "Password": "secret",
273
+ "Database": "my_application",
274
+ "ConnectionPoolLimit": 20,
275
+ "GlobalLogLevel": 0
276
+ },
277
+
278
+ "MSSQL": {
279
+ "Server": "localhost",
280
+ "Port": 1433,
281
+ "User": "sa",
282
+ "Password": "secret",
283
+ "Database": "my_application",
284
+ "ConnectionPoolLimit": 20,
285
+ "GlobalLogLevel": 0
286
+ },
287
+
288
+ "PostgreSQL": {
289
+ "Server": "localhost",
290
+ "Port": 5432,
291
+ "User": "postgres",
292
+ "Password": "secret",
293
+ "Database": "my_application",
294
+ "GlobalLogLevel": 0
295
+ },
296
+
297
+ "MeadowEndpoints": {
298
+ "ServerProtocol": "https",
299
+ "ServerAddress": "api.example.com",
300
+ "ServerPort": "443",
301
+ "ServerEndpointPrefix": "1.0/"
302
+ },
303
+
304
+ "MongoDB": {
305
+ "URL": "mongodb://localhost:27017",
306
+ "Database": "my_application",
307
+ "GlobalLogLevel": 0
308
+ },
309
+
310
+ "RocksDB": {
311
+ "KeyMode": "GUID",
312
+ "GlobalLogLevel": 0
313
+ }
314
+ }
315
+ ```
316
+
317
+ Note that you only need to include configuration for the provider you are using. Including unused provider settings has no effect.
@@ -0,0 +1,306 @@
1
+ # MeadowEndpoints Provider
2
+
3
+ > HTTP proxy to remote Meadow REST APIs using the same Meadow interface
4
+
5
+ The MeadowEndpoints provider enables client-side JavaScript to use the same Meadow CRUD interface while delegating actual data operations to a remote Meadow REST API server. Instead of connecting to a database directly, it translates Meadow operations into HTTP requests using [simple-get](https://github.com/feross/simple-get). No external connection module is required -- the HTTP transport is built in.
6
+
7
+ ## Setup
8
+
9
+ ### Install Dependencies
10
+
11
+ ```bash
12
+ npm install meadow
13
+ ```
14
+
15
+ No external connection module is needed. The MeadowEndpoints provider uses `simple-get` (bundled with Meadow) for HTTP communication.
16
+
17
+ ### Configure the Remote Server
18
+
19
+ ```javascript
20
+ const libFable = require('fable').new(
21
+ {
22
+ MeadowEndpoints:
23
+ {
24
+ ServerProtocol: 'http',
25
+ ServerAddress: '127.0.0.1',
26
+ ServerPort: 8086,
27
+ ServerEndpointPrefix: '1.0/'
28
+ }
29
+ });
30
+ ```
31
+
32
+ ### Create a Meadow DAL
33
+
34
+ ```javascript
35
+ const libMeadow = require('meadow');
36
+
37
+ const meadow = libMeadow.new(libFable, 'Book')
38
+ .setProvider('MeadowEndpoints')
39
+ .setDefaultIdentifier('IDBook')
40
+ .setSchema([
41
+ { Column: 'IDBook', Type: 'AutoIdentity' },
42
+ { Column: 'GUIDBook', Type: 'AutoGUID' },
43
+ { Column: 'Title', Type: 'String', Size: '255' },
44
+ { Column: 'Author', Type: 'String', Size: '128' },
45
+ { Column: 'CreateDate', Type: 'CreateDate' },
46
+ { Column: 'CreatingIDUser', Type: 'CreateIDUser' },
47
+ { Column: 'UpdateDate', Type: 'UpdateDate' },
48
+ { Column: 'UpdatingIDUser', Type: 'UpdateIDUser' },
49
+ { Column: 'DeleteDate', Type: 'DeleteDate' },
50
+ { Column: 'DeletingIDUser', Type: 'DeleteIDUser' },
51
+ { Column: 'Deleted', Type: 'Deleted' }
52
+ ]);
53
+ ```
54
+
55
+ ## Connection Configuration
56
+
57
+ | Setting | Type | Default | Description |
58
+ |---------|------|---------|-------------|
59
+ | `MeadowEndpoints.ServerProtocol` | string | -- | HTTP protocol (`'http'` or `'https'`) |
60
+ | `MeadowEndpoints.ServerAddress` | string | -- | Remote server hostname or IP address |
61
+ | `MeadowEndpoints.ServerPort` | number | -- | Remote server port |
62
+ | `MeadowEndpoints.ServerEndpointPrefix` | string | -- | URL path prefix for API endpoints (e.g., `'1.0/'`) |
63
+
64
+ ### URL Construction
65
+
66
+ The provider constructs endpoint URLs from the configuration settings:
67
+
68
+ ```
69
+ {ServerProtocol}://{ServerAddress}:{ServerPort}/{ServerEndpointPrefix}{Scope}/{Operation}
70
+ ```
71
+
72
+ For example, with the default configuration and a `Book` scope:
73
+
74
+ ```
75
+ http://127.0.0.1:8086/1.0/Book
76
+ http://127.0.0.1:8086/1.0/Books
77
+ http://127.0.0.1:8086/1.0/Book/42
78
+ http://127.0.0.1:8086/1.0/Books/Count
79
+ ```
80
+
81
+ ## HTTP Method Mapping
82
+
83
+ Each Meadow CRUD operation maps to a standard HTTP method:
84
+
85
+ | HTTP Method | Meadow Operation | Endpoint Pattern |
86
+ |-------------|------------------|------------------|
87
+ | `POST` | Create | `/{prefix}{Scope}` |
88
+ | `GET` | Read | `/{prefix}{Scope}/{ID}` |
89
+ | `GET` | Reads | `/{prefix}{Scope}s` |
90
+ | `GET` | Count | `/{prefix}{Scope}s/Count` |
91
+ | `PUT` | Update | `/{prefix}{Scope}` |
92
+ | `DELETE` | Delete | `/{prefix}{Scope}/{ID}` |
93
+
94
+ This mapping follows the standard Meadow REST conventions generated by [meadow-endpoints](https://github.com/stevenvelozo/meadow-endpoints) on the server side.
95
+
96
+ ## Cookie and Header Forwarding
97
+
98
+ The MeadowEndpoints provider forwards cookies and headers from the client to the remote server. This enables transparent authentication and session management -- if the client has an authenticated session with the server, the provider carries those credentials through on every request.
99
+
100
+ ## CRUD Operations
101
+
102
+ ### Create
103
+
104
+ Sends a POST request with the record data as the JSON body.
105
+
106
+ ```javascript
107
+ meadow.doCreate(
108
+ meadow.query.addRecord({ Title: 'Dune', Author: 'Frank Herbert' }),
109
+ (pError, pCreateQuery, pReadQuery, pRecord) =>
110
+ {
111
+ console.log('New ID:', pRecord.IDBook);
112
+ });
113
+ ```
114
+
115
+ **HTTP request:**
116
+ ```
117
+ POST http://127.0.0.1:8086/1.0/Book
118
+ Content-Type: application/json
119
+
120
+ { "Title": "Dune", "Author": "Frank Herbert" }
121
+ ```
122
+
123
+ ### Read
124
+
125
+ Sends a GET request to retrieve a single record by identifier.
126
+
127
+ ```javascript
128
+ meadow.doRead(
129
+ meadow.query.addFilter('IDBook', 42),
130
+ (pError, pQuery, pRecord) =>
131
+ {
132
+ console.log('Title:', pRecord.Title);
133
+ });
134
+ ```
135
+
136
+ **HTTP request:**
137
+ ```
138
+ GET http://127.0.0.1:8086/1.0/Book/42
139
+ ```
140
+
141
+ ### Reads
142
+
143
+ Sends a GET request to retrieve multiple records with optional filtering and pagination.
144
+
145
+ ```javascript
146
+ meadow.doReads(
147
+ meadow.query.setCap(25).setBegin(0),
148
+ (pError, pQuery, pRecords) =>
149
+ {
150
+ pRecords.forEach((pBook) => console.log(pBook.Title));
151
+ });
152
+ ```
153
+
154
+ **HTTP request:**
155
+ ```
156
+ GET http://127.0.0.1:8086/1.0/Books
157
+ ```
158
+
159
+ ### Update
160
+
161
+ Sends a PUT request with the updated record data as the JSON body.
162
+
163
+ ```javascript
164
+ meadow.doUpdate(
165
+ meadow.query
166
+ .addFilter('IDBook', 42)
167
+ .addRecord({ Title: 'Updated Title' }),
168
+ (pError, pUpdateQuery, pReadQuery, pRecord) =>
169
+ {
170
+ console.log('Updated:', pRecord.Title);
171
+ });
172
+ ```
173
+
174
+ **HTTP request:**
175
+ ```
176
+ PUT http://127.0.0.1:8086/1.0/Book
177
+ Content-Type: application/json
178
+
179
+ { "IDBook": 42, "Title": "Updated Title" }
180
+ ```
181
+
182
+ ### Delete
183
+
184
+ Sends a DELETE request to soft-delete a record by identifier.
185
+
186
+ ```javascript
187
+ meadow.doDelete(
188
+ meadow.query.addFilter('IDBook', 42),
189
+ (pError, pQuery, pResult) =>
190
+ {
191
+ console.log('Deleted:', pResult);
192
+ });
193
+ ```
194
+
195
+ **HTTP request:**
196
+ ```
197
+ DELETE http://127.0.0.1:8086/1.0/Book/42
198
+ ```
199
+
200
+ ### Count
201
+
202
+ Sends a GET request to the count endpoint.
203
+
204
+ ```javascript
205
+ meadow.doCount(
206
+ meadow.query,
207
+ (pError, pQuery, pCount) =>
208
+ {
209
+ console.log('Total books:', pCount);
210
+ });
211
+ ```
212
+
213
+ **HTTP request:**
214
+ ```
215
+ GET http://127.0.0.1:8086/1.0/Books/Count
216
+ ```
217
+
218
+ ## Use Case: Unified Client-Server Interface
219
+
220
+ The primary use case for MeadowEndpoints is enabling client-side JavaScript to use the same Meadow data access interface that the server uses. This means your application logic can be written once and run in either context:
221
+
222
+ ```
223
+ Browser / Client Server
224
+ ┌──────────────────┐ ┌──────────────────┐
225
+ │ Application Code │ │ Application Code │
226
+ │ │ │ │
227
+ │ Meadow DAL │ │ Meadow DAL │
228
+ │ Provider: │ HTTP/REST │ Provider: │
229
+ │ MeadowEndpoints ─┼──────────────────>│ MySQL │
230
+ │ │ │ │
231
+ └──────────────────┘ └──────────────────┘
232
+ ```
233
+
234
+ - **Server side:** Meadow uses a database provider (MySQL, MSSQL, PostgreSQL, etc.) to interact with the database directly
235
+ - **Client side:** Meadow uses MeadowEndpoints to proxy the same operations over HTTP to the server's REST API
236
+ - **Application code:** Identical CRUD calls in both environments
237
+
238
+ This pattern is especially powerful when combined with [meadow-endpoints](https://github.com/stevenvelozo/meadow-endpoints) on the server, which auto-generates REST routes from Meadow entity definitions.
239
+
240
+ ## Full Setup Example
241
+
242
+ A complete working example showing client-side Meadow proxying to a remote server:
243
+
244
+ ```javascript
245
+ const libFable = require('fable').new(
246
+ {
247
+ MeadowEndpoints:
248
+ {
249
+ ServerProtocol: 'https',
250
+ ServerAddress: 'api.example.com',
251
+ ServerPort: 443,
252
+ ServerEndpointPrefix: '1.0/'
253
+ }
254
+ });
255
+
256
+ const libMeadow = require('meadow');
257
+
258
+ // Create the DAL with MeadowEndpoints provider
259
+ const meadow = libMeadow.new(libFable, 'Book')
260
+ .setProvider('MeadowEndpoints')
261
+ .setDefaultIdentifier('IDBook')
262
+ .setSchema([
263
+ { Column: 'IDBook', Type: 'AutoIdentity' },
264
+ { Column: 'GUIDBook', Type: 'AutoGUID' },
265
+ { Column: 'Title', Type: 'String', Size: '255' },
266
+ { Column: 'Author', Type: 'String', Size: '128' },
267
+ { Column: 'CreateDate', Type: 'CreateDate' },
268
+ { Column: 'CreatingIDUser', Type: 'CreateIDUser' },
269
+ { Column: 'UpdateDate', Type: 'UpdateDate' },
270
+ { Column: 'UpdatingIDUser', Type: 'UpdateIDUser' },
271
+ { Column: 'DeleteDate', Type: 'DeleteDate' },
272
+ { Column: 'DeletingIDUser', Type: 'DeleteIDUser' },
273
+ { Column: 'Deleted', Type: 'Deleted' }
274
+ ]);
275
+
276
+ // These calls transparently proxy to the remote server
277
+ meadow.doCreate(
278
+ meadow.query.addRecord({ Title: 'Dune', Author: 'Frank Herbert' }),
279
+ (pError, pCreateQuery, pReadQuery, pRecord) =>
280
+ {
281
+ console.log('Created book with ID:', pRecord.IDBook);
282
+
283
+ // Read it back from the server
284
+ meadow.doRead(
285
+ meadow.query.addFilter('IDBook', pRecord.IDBook),
286
+ (pError, pQuery, pRecord) =>
287
+ {
288
+ console.log('Read back:', pRecord.Title, 'by', pRecord.Author);
289
+ });
290
+ });
291
+ ```
292
+
293
+ ## Error Handling
294
+
295
+ HTTP-related errors follow the standard pattern:
296
+
297
+ - Network errors (connection refused, timeouts) are returned as `pError` in the callback
298
+ - HTTP error status codes (4xx, 5xx) are stored in `pQuery.parameters.result.error`
299
+ - Response parsing failures are logged and reported through the error callback
300
+
301
+ ## Related Documentation
302
+
303
+ - [Providers Overview](providers/README.md) -- Comparison of all providers
304
+ - [MySQL Provider](providers/mysql.md) -- Server-side database provider
305
+ - [ALASQL Provider](providers/alasql.md) -- Client-side in-memory alternative
306
+ - [meadow-endpoints](https://github.com/stevenvelozo/meadow-endpoints) -- Server-side REST API generation