local-serverless-stack 0.6.0 → 0.9.0

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 (257) hide show
  1. package/CHANGELOG.md +104 -0
  2. package/README.md +261 -583
  3. package/bin/cli.js +31 -3
  4. package/dist/client/types.d.ts +4 -0
  5. package/dist/client/types.d.ts.map +1 -1
  6. package/dist/server/engine/aoss-sidecar.d.ts +13 -0
  7. package/dist/server/engine/aoss-sidecar.d.ts.map +1 -0
  8. package/dist/server/engine/aoss-sidecar.js +93 -0
  9. package/dist/server/engine/aoss-sidecar.js.map +1 -0
  10. package/dist/server/engine/backends/localstack-backend.d.ts +25 -0
  11. package/dist/server/engine/backends/localstack-backend.d.ts.map +1 -0
  12. package/dist/server/engine/backends/localstack-backend.js +199 -0
  13. package/dist/server/engine/backends/localstack-backend.js.map +1 -0
  14. package/dist/server/engine/backends/self-backend.d.ts +32 -0
  15. package/dist/server/engine/backends/self-backend.d.ts.map +1 -0
  16. package/dist/server/engine/backends/self-backend.js +207 -0
  17. package/dist/server/engine/backends/self-backend.js.map +1 -0
  18. package/dist/server/engine/bus.d.ts +10 -0
  19. package/dist/server/engine/bus.d.ts.map +1 -0
  20. package/dist/server/engine/bus.js +24 -0
  21. package/dist/server/engine/bus.js.map +1 -0
  22. package/dist/server/engine/dispatch/dispatcher.d.ts +46 -0
  23. package/dist/server/engine/dispatch/dispatcher.d.ts.map +1 -0
  24. package/dist/server/engine/dispatch/dispatcher.js +312 -0
  25. package/dist/server/engine/dispatch/dispatcher.js.map +1 -0
  26. package/dist/server/engine/dispatch/scheduler.d.ts +47 -0
  27. package/dist/server/engine/dispatch/scheduler.d.ts.map +1 -0
  28. package/dist/server/engine/dispatch/scheduler.js +328 -0
  29. package/dist/server/engine/dispatch/scheduler.js.map +1 -0
  30. package/dist/server/engine/dispatch/sqs-poller.d.ts +25 -0
  31. package/dist/server/engine/dispatch/sqs-poller.d.ts.map +1 -0
  32. package/dist/server/engine/dispatch/sqs-poller.js +242 -0
  33. package/dist/server/engine/dispatch/sqs-poller.js.map +1 -0
  34. package/dist/server/engine/dispatch/stream-tailer.d.ts +22 -0
  35. package/dist/server/engine/dispatch/stream-tailer.d.ts.map +1 -0
  36. package/dist/server/engine/dispatch/stream-tailer.js +205 -0
  37. package/dist/server/engine/dispatch/stream-tailer.js.map +1 -0
  38. package/dist/server/engine/emulators/dynamodb/expressions/decimal.d.ts +5 -0
  39. package/dist/server/engine/emulators/dynamodb/expressions/decimal.d.ts.map +1 -0
  40. package/dist/server/engine/emulators/dynamodb/expressions/decimal.js +91 -0
  41. package/dist/server/engine/emulators/dynamodb/expressions/decimal.js.map +1 -0
  42. package/dist/server/engine/emulators/dynamodb/expressions/evaluate.d.ts +24 -0
  43. package/dist/server/engine/emulators/dynamodb/expressions/evaluate.d.ts.map +1 -0
  44. package/dist/server/engine/emulators/dynamodb/expressions/evaluate.js +183 -0
  45. package/dist/server/engine/emulators/dynamodb/expressions/evaluate.js.map +1 -0
  46. package/dist/server/engine/emulators/dynamodb/expressions/expression-types.d.ts +29 -0
  47. package/dist/server/engine/emulators/dynamodb/expressions/expression-types.d.ts.map +1 -0
  48. package/dist/server/engine/emulators/dynamodb/expressions/expression-types.js +12 -0
  49. package/dist/server/engine/emulators/dynamodb/expressions/expression-types.js.map +1 -0
  50. package/dist/server/engine/emulators/dynamodb/expressions/index.d.ts +13 -0
  51. package/dist/server/engine/emulators/dynamodb/expressions/index.d.ts.map +1 -0
  52. package/dist/server/engine/emulators/dynamodb/expressions/index.js +244 -0
  53. package/dist/server/engine/emulators/dynamodb/expressions/index.js.map +1 -0
  54. package/dist/server/engine/emulators/dynamodb/expressions/lexer.d.ts +11 -0
  55. package/dist/server/engine/emulators/dynamodb/expressions/lexer.d.ts.map +1 -0
  56. package/dist/server/engine/emulators/dynamodb/expressions/lexer.js +109 -0
  57. package/dist/server/engine/emulators/dynamodb/expressions/lexer.js.map +1 -0
  58. package/dist/server/engine/emulators/dynamodb/expressions/parser.d.ts +23 -0
  59. package/dist/server/engine/emulators/dynamodb/expressions/parser.d.ts.map +1 -0
  60. package/dist/server/engine/emulators/dynamodb/expressions/parser.js +541 -0
  61. package/dist/server/engine/emulators/dynamodb/expressions/parser.js.map +1 -0
  62. package/dist/server/engine/emulators/dynamodb/index.d.ts +46 -0
  63. package/dist/server/engine/emulators/dynamodb/index.d.ts.map +1 -0
  64. package/dist/server/engine/emulators/dynamodb/index.js +572 -0
  65. package/dist/server/engine/emulators/dynamodb/index.js.map +1 -0
  66. package/dist/server/engine/emulators/dynamodb/query.d.ts +12 -0
  67. package/dist/server/engine/emulators/dynamodb/query.d.ts.map +1 -0
  68. package/dist/server/engine/emulators/dynamodb/query.js +237 -0
  69. package/dist/server/engine/emulators/dynamodb/query.js.map +1 -0
  70. package/dist/server/engine/emulators/dynamodb/schema.d.ts +58 -0
  71. package/dist/server/engine/emulators/dynamodb/schema.d.ts.map +1 -0
  72. package/dist/server/engine/emulators/dynamodb/schema.js +284 -0
  73. package/dist/server/engine/emulators/dynamodb/schema.js.map +1 -0
  74. package/dist/server/engine/emulators/dynamodb/streams.d.ts +28 -0
  75. package/dist/server/engine/emulators/dynamodb/streams.d.ts.map +1 -0
  76. package/dist/server/engine/emulators/dynamodb/streams.js +100 -0
  77. package/dist/server/engine/emulators/dynamodb/streams.js.map +1 -0
  78. package/dist/server/engine/emulators/events/index.d.ts +53 -0
  79. package/dist/server/engine/emulators/events/index.d.ts.map +1 -0
  80. package/dist/server/engine/emulators/events/index.js +417 -0
  81. package/dist/server/engine/emulators/events/index.js.map +1 -0
  82. package/dist/server/engine/emulators/events/pattern.d.ts +3 -0
  83. package/dist/server/engine/emulators/events/pattern.d.ts.map +1 -0
  84. package/dist/server/engine/emulators/events/pattern.js +125 -0
  85. package/dist/server/engine/emulators/events/pattern.js.map +1 -0
  86. package/dist/server/engine/emulators/lambda-ctl/index.d.ts +55 -0
  87. package/dist/server/engine/emulators/lambda-ctl/index.d.ts.map +1 -0
  88. package/dist/server/engine/emulators/lambda-ctl/index.js +461 -0
  89. package/dist/server/engine/emulators/lambda-ctl/index.js.map +1 -0
  90. package/dist/server/engine/emulators/opensearch/index.d.ts +67 -0
  91. package/dist/server/engine/emulators/opensearch/index.d.ts.map +1 -0
  92. package/dist/server/engine/emulators/opensearch/index.js +811 -0
  93. package/dist/server/engine/emulators/opensearch/index.js.map +1 -0
  94. package/dist/server/engine/emulators/opensearch/search.d.ts +17 -0
  95. package/dist/server/engine/emulators/opensearch/search.d.ts.map +1 -0
  96. package/dist/server/engine/emulators/opensearch/search.js +434 -0
  97. package/dist/server/engine/emulators/opensearch/search.js.map +1 -0
  98. package/dist/server/engine/emulators/s3/index.d.ts +45 -0
  99. package/dist/server/engine/emulators/s3/index.d.ts.map +1 -0
  100. package/dist/server/engine/emulators/s3/index.js +591 -0
  101. package/dist/server/engine/emulators/s3/index.js.map +1 -0
  102. package/dist/server/engine/emulators/sns/index.d.ts +22 -0
  103. package/dist/server/engine/emulators/sns/index.d.ts.map +1 -0
  104. package/dist/server/engine/emulators/sns/index.js +135 -0
  105. package/dist/server/engine/emulators/sns/index.js.map +1 -0
  106. package/dist/server/engine/emulators/sqs/index.d.ts +66 -0
  107. package/dist/server/engine/emulators/sqs/index.d.ts.map +1 -0
  108. package/dist/server/engine/emulators/sqs/index.js +552 -0
  109. package/dist/server/engine/emulators/sqs/index.js.map +1 -0
  110. package/dist/server/engine/emulators/sqs/md5.d.ts +8 -0
  111. package/dist/server/engine/emulators/sqs/md5.d.ts.map +1 -0
  112. package/dist/server/engine/emulators/sqs/md5.js +36 -0
  113. package/dist/server/engine/emulators/sqs/md5.js.map +1 -0
  114. package/dist/server/engine/emulators/sqs/queue.d.ts +105 -0
  115. package/dist/server/engine/emulators/sqs/queue.d.ts.map +1 -0
  116. package/dist/server/engine/emulators/sqs/queue.js +371 -0
  117. package/dist/server/engine/emulators/sqs/queue.js.map +1 -0
  118. package/dist/server/engine/emulators/sts.d.ts +8 -0
  119. package/dist/server/engine/emulators/sts.d.ts.map +1 -0
  120. package/dist/server/engine/emulators/sts.js +23 -0
  121. package/dist/server/engine/emulators/sts.js.map +1 -0
  122. package/dist/server/engine/engine-backend.d.ts +17 -0
  123. package/dist/server/engine/engine-backend.d.ts.map +1 -0
  124. package/dist/server/engine/engine-backend.js +7 -0
  125. package/dist/server/engine/engine-backend.js.map +1 -0
  126. package/dist/server/engine/engine-manager.d.ts +22 -0
  127. package/dist/server/engine/engine-manager.d.ts.map +1 -0
  128. package/dist/server/engine/engine-manager.js +74 -0
  129. package/dist/server/engine/engine-manager.js.map +1 -0
  130. package/dist/server/engine/http/aws-chunked.d.ts +3 -0
  131. package/dist/server/engine/http/aws-chunked.d.ts.map +1 -0
  132. package/dist/server/engine/http/aws-chunked.js +50 -0
  133. package/dist/server/engine/http/aws-chunked.js.map +1 -0
  134. package/dist/server/engine/http/errors.d.ts +20 -0
  135. package/dist/server/engine/http/errors.d.ts.map +1 -0
  136. package/dist/server/engine/http/errors.js +43 -0
  137. package/dist/server/engine/http/errors.js.map +1 -0
  138. package/dist/server/engine/http/protocols/aws-json.d.ts +8 -0
  139. package/dist/server/engine/http/protocols/aws-json.d.ts.map +1 -0
  140. package/dist/server/engine/http/protocols/aws-json.js +42 -0
  141. package/dist/server/engine/http/protocols/aws-json.js.map +1 -0
  142. package/dist/server/engine/http/protocols/query-xml.d.ts +7 -0
  143. package/dist/server/engine/http/protocols/query-xml.d.ts.map +1 -0
  144. package/dist/server/engine/http/protocols/query-xml.js +35 -0
  145. package/dist/server/engine/http/protocols/query-xml.js.map +1 -0
  146. package/dist/server/engine/http/router.d.ts +8 -0
  147. package/dist/server/engine/http/router.d.ts.map +1 -0
  148. package/dist/server/engine/http/router.js +402 -0
  149. package/dist/server/engine/http/router.js.map +1 -0
  150. package/dist/server/engine/http/sigv4.d.ts +9 -0
  151. package/dist/server/engine/http/sigv4.d.ts.map +1 -0
  152. package/dist/server/engine/http/sigv4.js +33 -0
  153. package/dist/server/engine/http/sigv4.js.map +1 -0
  154. package/dist/server/engine/http/xml.d.ts +16 -0
  155. package/dist/server/engine/http/xml.d.ts.map +1 -0
  156. package/dist/server/engine/http/xml.js +92 -0
  157. package/dist/server/engine/http/xml.js.map +1 -0
  158. package/dist/server/engine/store/atomic.d.ts +4 -0
  159. package/dist/server/engine/store/atomic.d.ts.map +1 -0
  160. package/dist/server/engine/store/atomic.js +35 -0
  161. package/dist/server/engine/store/atomic.js.map +1 -0
  162. package/dist/server/engine/store/engine-store.d.ts +9 -0
  163. package/dist/server/engine/store/engine-store.d.ts.map +1 -0
  164. package/dist/server/engine/store/engine-store.js +218 -0
  165. package/dist/server/engine/store/engine-store.js.map +1 -0
  166. package/dist/server/engine/store/store-types.d.ts +37 -0
  167. package/dist/server/engine/store/store-types.d.ts.map +1 -0
  168. package/dist/server/engine/store/store-types.js +17 -0
  169. package/dist/server/engine/store/store-types.js.map +1 -0
  170. package/dist/server/engine/store/wal.d.ts +49 -0
  171. package/dist/server/engine/store/wal.d.ts.map +1 -0
  172. package/dist/server/engine/store/wal.js +328 -0
  173. package/dist/server/engine/store/wal.js.map +1 -0
  174. package/dist/server/engine/types.d.ts +137 -0
  175. package/dist/server/engine/types.d.ts.map +1 -0
  176. package/dist/server/engine/types.js +8 -0
  177. package/dist/server/engine/types.js.map +1 -0
  178. package/dist/server/index.js +43 -9
  179. package/dist/server/index.js.map +1 -1
  180. package/dist/server/routes/config.d.ts.map +1 -1
  181. package/dist/server/routes/config.js +16 -0
  182. package/dist/server/routes/config.js.map +1 -1
  183. package/dist/server/routes/opensearch.d.ts +3 -0
  184. package/dist/server/routes/opensearch.d.ts.map +1 -0
  185. package/dist/server/routes/opensearch.js +69 -0
  186. package/dist/server/routes/opensearch.js.map +1 -0
  187. package/dist/server/routes/resources.d.ts.map +1 -1
  188. package/dist/server/routes/resources.js +4 -1
  189. package/dist/server/routes/resources.js.map +1 -1
  190. package/dist/server/routes/services.d.ts.map +1 -1
  191. package/dist/server/routes/services.js +3 -0
  192. package/dist/server/routes/services.js.map +1 -1
  193. package/dist/server/services/cache-manager.d.ts +2 -1
  194. package/dist/server/services/cache-manager.d.ts.map +1 -1
  195. package/dist/server/services/cache-manager.js +22 -2
  196. package/dist/server/services/cache-manager.js.map +1 -1
  197. package/dist/server/services/cloudformation-parser.d.ts +35 -2
  198. package/dist/server/services/cloudformation-parser.d.ts.map +1 -1
  199. package/dist/server/services/cloudformation-parser.js +88 -3
  200. package/dist/server/services/cloudformation-parser.js.map +1 -1
  201. package/dist/server/services/config-manager.d.ts +82 -0
  202. package/dist/server/services/config-manager.d.ts.map +1 -1
  203. package/dist/server/services/config-manager.js +151 -7
  204. package/dist/server/services/config-manager.js.map +1 -1
  205. package/dist/server/services/gateway-manager.d.ts +2 -0
  206. package/dist/server/services/gateway-manager.d.ts.map +1 -1
  207. package/dist/server/services/gateway-manager.js +44 -6
  208. package/dist/server/services/gateway-manager.js.map +1 -1
  209. package/dist/server/services/localstack-manager.d.ts +0 -7
  210. package/dist/server/services/localstack-manager.d.ts.map +1 -1
  211. package/dist/server/services/localstack-manager.js +11 -173
  212. package/dist/server/services/localstack-manager.js.map +1 -1
  213. package/dist/server/services/opensearch-explorer.d.ts +37 -0
  214. package/dist/server/services/opensearch-explorer.d.ts.map +1 -0
  215. package/dist/server/services/opensearch-explorer.js +124 -0
  216. package/dist/server/services/opensearch-explorer.js.map +1 -0
  217. package/dist/server/services/resource-provisioner.d.ts +13 -0
  218. package/dist/server/services/resource-provisioner.d.ts.map +1 -1
  219. package/dist/server/services/resource-provisioner.js +257 -11
  220. package/dist/server/services/resource-provisioner.js.map +1 -1
  221. package/dist/server/services/service-registrar.d.ts +1 -0
  222. package/dist/server/services/service-registrar.d.ts.map +1 -1
  223. package/dist/server/services/service-registrar.js +19 -4
  224. package/dist/server/services/service-registrar.js.map +1 -1
  225. package/dist/ui/assets/ApisPage-C0xaNFQW.js +1 -0
  226. package/dist/ui/assets/BucketDetailPage-Bnny8S04.js +1 -0
  227. package/dist/ui/assets/BucketsPage-Dd3Y4-gU.js +1 -0
  228. package/dist/ui/assets/{DynamoPage-B1__Rjr2.js → DynamoPage-JzSF-4VI.js} +1 -1
  229. package/dist/ui/assets/DynamoTablePage-uM0DXGCo.js +3 -0
  230. package/dist/ui/assets/LambdaDetailPage-CoR9ZXdb.js +4 -0
  231. package/dist/ui/assets/LambdasPage-CNMX_O5P.js +1 -0
  232. package/dist/ui/assets/OpenSearchCollectionPage-D5FaSCF1.js +1 -0
  233. package/dist/ui/assets/OpenSearchPage-FEzLxaej.js +1 -0
  234. package/dist/ui/assets/OverviewPage-0xvjT7Q0.js +1 -0
  235. package/dist/ui/assets/OverviewPage-qEl0a-0B.css +1 -0
  236. package/dist/ui/assets/QueueDetailPage-B2GaNLLe.js +1 -0
  237. package/dist/ui/assets/QueuesPage-Ch5kGwrp.js +1 -0
  238. package/dist/ui/assets/ServiceDetailPage-DKiz21oo.js +2 -0
  239. package/dist/ui/assets/ServicesPage-Cmi3UIfM.js +2 -0
  240. package/dist/ui/assets/index-DH7RTkRh.css +1 -0
  241. package/dist/ui/assets/index-MF9fVrsr.js +37 -0
  242. package/dist/ui/index.html +2 -2
  243. package/package.json +3 -1
  244. package/dist/ui/assets/ApisPage-DdgKjEdS.js +0 -1
  245. package/dist/ui/assets/BucketDetailPage-DZQGxm0y.js +0 -1
  246. package/dist/ui/assets/BucketsPage-xYXzxCvd.js +0 -1
  247. package/dist/ui/assets/DynamoTablePage-BCoxPdXW.js +0 -3
  248. package/dist/ui/assets/LambdaDetailPage-B85CA8tb.js +0 -4
  249. package/dist/ui/assets/LambdasPage-_TtxQMT_.js +0 -1
  250. package/dist/ui/assets/OverviewPage-6jDXV1jr.css +0 -1
  251. package/dist/ui/assets/OverviewPage-CqTKTY64.js +0 -1
  252. package/dist/ui/assets/QueueDetailPage-BOr_sImA.js +0 -1
  253. package/dist/ui/assets/QueuesPage-DpByfcM5.js +0 -1
  254. package/dist/ui/assets/ServiceDetailPage-DsWgV-ad.js +0 -2
  255. package/dist/ui/assets/ServicesPage-CGlpsj98.js +0 -2
  256. package/dist/ui/assets/index-BWlB542w.js +0 -36
  257. package/dist/ui/assets/index-EYnsoJOq.css +0 -1
package/README.md CHANGED
@@ -2,692 +2,370 @@
2
2
 
3
3
  [![npm version](https://img.shields.io/npm/v/local-serverless-stack.svg)](https://www.npmjs.com/package/local-serverless-stack)
4
4
 
5
- **Local control plane for serverless development with LocalStack orchestration**
5
+ **Local control plane for serverless development with its own in-process AWS engine (no Docker) or LocalStack orchestration**
6
6
 
7
- LSS provides a unified local development environment for serverless microservices, eliminating the need to run separate LocalStack instances for each service.
7
+ LSS provides a unified local development environment for serverless microservices: one orchestrator provisions and serves every AWS resource your services declare, eliminating the need to run separate LocalStack instances (or, with the **self engine**, any LocalStack at all). It scales to monorepos with 15+ microservices sharing one stack.
8
+
9
+ ```mermaid
10
+ flowchart LR
11
+ DEV[Developer] -->|npx lss start| CLI[CLI<br/>bin/cli.js]
12
+ CLI --> ORCH[Orchestrator<br/>Express API + dashboard :3100]
13
+ SVC[Your services<br/>serverless.yml + serverless-lss] -->|sls package → register| ORCH
14
+ ORCH -->|provision + events| ENGINE{Engine}
15
+ ENGINE -->|"engine: self"| SELF[Self engine<br/>in-process :14566]
16
+ ENGINE -->|"engine: localstack"| LS[LocalStack<br/>Docker :4566]
17
+ ORCH --> RT[Lambda runtime + API Gateway emulation<br/>your handlers, ports 30xx/130xx]
18
+ ```
8
19
 
9
20
  ## Features
10
21
 
11
- - **Centralized LocalStack**: Single LocalStack instance manages DynamoDB, SQS, SNS, S3, and Lambda
12
- - **Auto-provisioning**: Parses CloudFormation templates from `sls package` and provisions resources automatically
13
- - **Event source mappings**: Automatically connects SQS queues, streams, and S3 notifications to Lambda handlers via LocalStack
14
- - **Lambda runtime & API emulation**: LSS can answer on the same API (30xx) and Lambda invoke (130xx) ports that serverless-offline used
15
- - **Web UI**: Vue 3 dashboard to monitor services, resources, and event mappings
22
+ - **⚡ Self engine (the LSS differentiator)**: DynamoDB, SQS, S3, EventBridge, OpenSearch Serverless, SNS and the Lambda control plane emulated **in-process** by the orchestrator — no Docker, no LocalStack, no auth token. Boots in milliseconds, stores data in local files, delivers events straight into your handlers. See [Self engine](#self-engine--no-docker-no-localstack-no-auth-token) below.
23
+ - **Centralized provisioning**: Parses CloudFormation templates from `sls package` and provisions resources automatically — into the self engine or a single shared LocalStack, your choice per instance
24
+ - **Event source mappings**: Automatically connects SQS queues, streams, S3 notifications and EventBridge rules to Lambda handlers
25
+ - **Lambda runtime & API emulation**: LSS answers on the same API (30xx) and Lambda invoke (130xx) ports that serverless-offline used
26
+ - **Web UI**: Vue 3 dashboard to monitor services, resources, and event mappings — [brandable with your company's colors and logo](docs/CONFIGURATION.md#configuration-properties)
16
27
  - **Hot reload**: Watch for code changes and auto-rebuild/reprovision
17
- - **Process management**: Start/stop microservices from the orchestrator
18
- - **CLI Tool**: Simple commands to manage the orchestrator (start/stop/status/logs)
28
+ - **DynamoDB seeds**: fixtures auto-applied on table creation, re-applied via `lss seed` or the dashboard
29
+ - **CLI + programmatic client**: manage the orchestrator from the shell (`npx lss …`) or from code (`LssClient`)
19
30
 
20
31
  See [docs/FEATURES.md](docs/FEATURES.md) for the complete feature inventory and how each capability is tested.
21
32
 
22
- ## Architecture
23
-
24
- ```
25
- local-serverless-stack/
26
- ├── bin/ # CLI executable
27
- │ └── cli.js # lss command entry point
28
- ├── src/ # Source code
29
- │ ├── server/ # Express API + services
30
- │ │ ├── routes/ # API endpoints
31
- │ │ ├── services/ # Business logic
32
- │ │ └── dev/ # Dev utilities
33
- │ └── ui/ # Vue 3 dashboard
34
- ├── packages/
35
- │ └── serverless-plugin/ # Serverless Framework plugin (published separately)
36
- ├── dist/ # Build output
37
- │ ├── server/ # Compiled Express app
38
- │ └── ui/ # Built Vue app
39
- └── tests/ # Integration tests
40
- ```
41
-
42
- **Components**:
43
- - **CLI** (`bin/cli.js`): Background process management (start/stop/status/logs)
44
- - **Server** (`src/server/`): Express API + LocalStack orchestration
45
- - **UI** (`src/ui/`): Vue 3 dashboard for monitoring
46
- - **Plugin** (`packages/serverless-plugin/`): Auto-registration for Serverless Framework
47
- - **LocalStack**: Docker container (port 4566) with AWS services
48
-
49
- ## Quick Start
50
-
51
- ### Prerequisites
52
-
53
- - Node.js >= 20
54
- - Docker (for LocalStack)
55
- - Serverless Framework 3.40.0
56
-
57
- ### Installation
58
-
59
- ```bash
60
- npm install -g local-serverless-stack
61
- ```
62
-
63
- Or install locally:
64
-
65
- ```bash
66
- cd /path/to/local-serverless-stack
67
- npm install
68
- npm run build
69
- npm link
70
- ```
71
-
72
- The `npm link` command makes the `lss` CLI available globally via `npx`.
33
+ ## Self engine — no Docker, no LocalStack, no auth token
73
34
 
74
- ### Serverless Framework Plugin
75
-
76
- To automatically register your microservices with LSS, install the Serverless plugin:
35
+ LocalStack got heavy (a container eating 1 GB+ of RAM) and stopped being free by default
36
+ (community images `>= 2026.5` require an auth token). The **self engine** replaces it for
37
+ the typical serverless dev loop: the orchestrator itself serves the real AWS wire
38
+ protocols on one port, so your application code, the AWS SDK, the dashboard and `lss seed`
39
+ all work unchanged — there is simply no container underneath.
77
40
 
78
41
  ```bash
79
- npm install --save-dev serverless-lss
42
+ npx lss start --self-engine # or "engine": "self" in lss.config.json
80
43
  ```
81
44
 
82
- See the [plugin documentation](packages/serverless-plugin/README.md) for configuration details.
83
-
84
- ## CLI Commands
85
-
86
- LSS provides a simple CLI to manage the orchestrator in background mode:
87
-
88
- ```bash
89
- # Start the orchestrator in background
90
- npx lss start
91
-
92
- # Check if orchestrator is running
93
- npx lss status
94
-
95
- # View recent logs
96
- npx lss logs
97
-
98
- # Stop the orchestrator
99
- npx lss stop
100
-
101
- # Show help
102
- npx lss help
103
45
  ```
104
-
105
- ### CLI Output
106
-
107
- ```bash
108
- $ npx lss start
109
- 🚀 LSS Orchestrator started (PID: 12345)
110
- 📊 Dashboard: http://localhost:3100
111
- 🔧 LocalStack: http://localhost:4566
112
- 📝 Logs: /tmp/lss-orchestrator.log
113
- ✅ Service is running
114
-
115
- $ npx lss status
116
- 🟢 LSS Orchestrator: RUNNING (PID: 12345)
117
- 📊 Dashboard: http://localhost:3100
118
- 🔧 LocalStack: http://localhost:4566
119
- 📝 Logs: /tmp/lss-orchestrator.log
46
+ AWS_ENDPOINT=http://localhost:14566 # point your services here, done
120
47
  ```
121
48
 
122
- ## Development Mode
49
+ What you get:
123
50
 
124
- For active development with hot reload:
51
+ - **DynamoDB** with the full expression language (KeyCondition/Filter/Update/Projection,
52
+ exact decimal arithmetic), GSIs/LSIs, TTL and streams — items persisted in local
53
+ JSONL files under `~/.lss/engine/`, hydrated lazily and unloaded when idle.
54
+ - **SQS** with FIFO, visibility redelivery and live counters; **S3** with byte-exact
55
+ object round trips and notifications; **EventBridge** with buses, pattern-filtered
56
+ rules and `rate()`/cron schedules; minimal **SNS** and **STS**.
57
+ - **OpenSearch Serverless**: collections declared as
58
+ `AWS::OpenSearchServerless::Collection` are provisioned via the real `aoss`
59
+ control plane and served through the OpenSearch REST API — document CRUD,
60
+ `_bulk`, `_search` with the everyday query DSL (match/term/range/bool…),
61
+ sorting and `terms`/metric aggregations — at
62
+ `http://localhost:14566/_aoss/<collection>`.
63
+ - **Events delivered in-process**: SQS batches, DynamoDB streams, S3 notifications and
64
+ EventBridge targets go straight from the engine to the LSS Lambda runtime — no proxy
65
+ Lambdas, no polling containers.
125
66
 
126
- ```bash
127
- npm run orchestrator:dev
67
+ ```mermaid
68
+ flowchart LR
69
+ APP[Your services<br/>AWS SDK → :14566] --> ENG
70
+ subgraph ORCH["One orchestrator process — no Docker"]
71
+ ENG[Self engine<br/>DynamoDB · SQS · S3 · EventBridge<br/>OpenSearch · SNS · STS]
72
+ ENG -->|in-process events| RT[LSS Lambda runtime<br/>your handlers, ports 30xx/130xx]
73
+ ENG --- FS[(local files<br/>~/.lss/engine)]
74
+ end
128
75
  ```
129
76
 
130
- This starts:
131
- - Orchestrator API on http://localhost:3100
132
- - LocalStack on http://localhost:4566
133
- - Web UI at http://localhost:3100
134
- - Auto-reload on code changes
77
+ Measured on [examples/self-hosted](examples/self-hosted/) (orders → billing →
78
+ notifications pipeline; the example also carries an OpenSearch catalog service):
79
+ engine boot **~10 ms**; a full pipeline crossing DynamoDB + SQS + S3 + EventBridge
80
+ across the three pipeline services completes in **~170 ms** — with the whole stack
81
+ being the orchestrator process plus one small worker per service.
135
82
 
136
- ## Integration with Projects
83
+ Migration is gradual: LocalStack mode remains the default and fully supported; a running
84
+ instance picks one engine. Anything the self engine doesn't implement yet answers with an
85
+ explicit error naming the operation — or is forwarded verbatim to a LocalStack via
86
+ `selfEngine.fallbackEndpoint`. Coverage matrix and storage model:
87
+ [docs/SELF_ENGINE.md](docs/SELF_ENGINE.md) · design/PRD:
88
+ [docs/PRD_SELF_ENGINE.md](docs/PRD_SELF_ENGINE.md) · runnable demo:
89
+ [examples/self-hosted](examples/self-hosted/).
137
90
 
138
- ### 1. Link LSS to Your Project
91
+ ## Quick Start
139
92
 
140
- In your project root:
93
+ Prerequisites: Node.js >= 20 · [osls](https://github.com/oss-serverless/serverless) 4.x (open-source Serverless Framework fork; provides the `serverless`/`sls` CLI) · Docker (**only** for the LocalStack engine)
141
94
 
142
95
  ```bash
143
- npm link local-serverless-stack
144
- ```
145
-
146
- ### 2. Install Plugin in Microservices
96
+ # 1. Install
97
+ npm install -g local-serverless-stack
147
98
 
148
- In each microservice directory:
99
+ # 2. Start the orchestrator (self engine: no Docker needed)
100
+ npx lss start --self-engine # or plain `npx lss start` for LocalStack
149
101
 
150
- ```bash
151
- npm link serverless-lss
102
+ # 3. In each microservice: install the plugin and add it to serverless.yml
103
+ npm install --save-dev serverless-lss
152
104
  ```
153
105
 
154
- ### 3. Configure serverless.yml
155
-
156
- Add the plugin to your `serverless.yml`:
157
-
158
106
  ```yaml
107
+ # serverless.yml
159
108
  plugins:
160
- - serverless-auto-swagger
161
- - serverless-esbuild
162
- - serverless-offline
163
- - serverless-localstack
164
- - serverless-lss # Add this line
109
+ - serverless-lss
165
110
 
166
111
  custom:
167
112
  orchestrator:
168
- url: http://localhost:3100 # optional, defaults to this
113
+ enabled: true
114
+ orchestratorUrl: http://localhost:3100 # must match serverPort
115
+ lss:
116
+ apiPort: 3000 # HTTP API (API Gateway emulation)
117
+ invokePort: 3001 # direct Lambda invocations
169
118
  ```
170
119
 
171
- ### 4. Workflow
172
-
173
120
  ```bash
174
- # 1. Start LSS Orchestrator
175
- npx lss start
176
-
177
- # 2. Package your microservice (auto-registers with LSS)
178
- cd your-microservice
121
+ # 4. Package the service — the plugin auto-registers it with LSS
122
+ # (registration also fires on `sls offline` startup)
179
123
  npx sls package
180
124
 
181
- # 3. Monitor in the dashboard
125
+ # 5. Watch everything in the dashboard
182
126
  open http://localhost:3100
183
127
  ```
184
128
 
185
- Now when you send a message to an SQS queue in LocalStack, the orchestrator will:
186
- 1. Detect the event via event source mapping
187
- 2. Invoke the Lambda proxy in LocalStack
188
- 3. Proxy calls LSS's Lambda invoke listener on the service invoke port
189
- 4. Your handler executes
129
+ A minimal template lives at [docs/serverless.yml.example](docs/serverless.yml.example);
130
+ complete runnable projects live in [examples/](examples/) one per engine flavor:
190
131
 
191
- If you still want serverless-offline to own the ports for a service, disable the
192
- LSS runtime globally or per service with `lambdaRuntime.enabled`/`serviceRuntime`.
132
+ | Example | Shows |
133
+ | --- | --- |
134
+ | [localstack-free](examples/localstack-free/) | LocalStack community 4.0 (Docker, no token): 3 services + a shared EventBridge bus — authorizers, SQS, schedules, DynamoDB stream → SNS, S3 notifications, seeds |
135
+ | [localstack-ultimate](examples/localstack-ultimate/) | LocalStack Pro image (Ultimate plan, auth token) with the serverless-offline path preserved |
136
+ | [self-hosted](examples/self-hosted/) | The no-Docker self engine end to end: orders → billing → notifications pipeline + an OpenSearch Serverless catalog |
193
137
 
194
- ## Project Structure
138
+ Each example ships an `index.html` validation console and its own dashboard
139
+ branding — see [examples/README.md](examples/README.md) for the full port map and
140
+ shared conventions.
195
141
 
196
- ```
197
- local-serverless-stack/
198
- bin/
199
- cli.js # CLI implementation (npx lss)
200
- package.json # Workspace root with bin config
201
- packages/
202
- orchestrator/ # Main orchestrator (Express + Vue UI)
203
- server/ # Backend (TypeScript)
204
- ui/ # Frontend (Vue 3 + Vite)
205
- dist/ # Compiled output
206
- serverless-plugin/ # Serverless Framework plugin
207
- src/index.ts # Plugin implementation
208
- dist/ # Compiled plugin
209
- docs/ # Documentation
210
- ```
211
-
212
- ## Configuration
213
-
214
- ### Environment Variables
215
-
216
- - `PORT`: Orchestrator API port (default: 3100)
217
- - `ENABLE_DYNAMO_PROXY`: Enable DynamoDB proxy on port 8000 (default: false)
218
- - `DYNAMO_PROXY_PORT`: DynamoDB proxy port (default: 8000)
219
-
220
- ### LocalStack Settings
221
-
222
- LocalStack is configured with:
223
- - Services: `dynamodb,sqs,sns,s3,lambda`
224
- - Persistence: Enabled (volume: `lss-localstack-data`)
225
- - Lambda executor: `local` (no Docker-in-Docker required)
226
- - Docker socket: Mounted from host
227
-
228
- #### Managed vs external mode
229
-
230
- By default LSS spins up its own LocalStack container. To point at an already-running instance (e.g. one you're sharing across projects) set `mode: "external"` in `lss.config.json` or pass `--external`:
142
+ ## CLI
231
143
 
232
144
  ```bash
233
- npx lss start --external # connect to whatever is on localstackEndpoint
145
+ npx lss start # start the orchestrator in background (managed LocalStack)
146
+ npx lss start --self-engine # …with the in-process self engine (no Docker)
147
+ npx lss start --external # …connecting to a LocalStack you already run
148
+ npx lss start --pro # …with the LocalStack Pro image (needs auth token)
149
+ npx lss start --pro --localstack-token ls-xxx # …passing the auth token inline
150
+ npx lss start --enable-dynamo-proxy # …with the DynamoDB proxy on :8000
151
+ npx lss start --config ./e2e/lss.config.json # explicit config file (any command)
152
+ npx lss status # is it running? which ports?
153
+ npx lss logs # tail the orchestrator log
154
+ npx lss seed [table] # apply DynamoDB seed files (all tables or one)
155
+ npx lss seed:clear [table] -y # empty seeded tables (prompts unless --yes)
156
+ npx lss stop # stop the orchestrator (and managed LocalStack)
157
+ npx lss help # all commands, flags and a config template
234
158
  ```
235
159
 
236
- #### Edition and auth token
237
-
238
- Recent LocalStack images (`>= 2026.5` for community, all `pro` builds) require `LOCALSTACK_AUTH_TOKEN`. Provide it via env var (preferred) or `--localstack-token`:
239
-
240
160
  ```bash
241
- export LOCALSTACK_AUTH_TOKEN=ls-xxxxxxxx
242
- npx lss start # community image with token
243
- npx lss start --pro # pro image (token required)
244
- ```
245
-
246
- See [docs/CONFIGURATION.md](docs/CONFIGURATION.md) for the full reference (`mode`, `localstackEdition`, `localstackVersion`, `localstackImage`, `localstackAuthToken`).
247
-
248
- ## Development
249
-
250
- ### Build All Packages
251
-
252
- ```bash
253
- npm run build
254
- ```
255
-
256
- ### Build Individual Packages
257
-
258
- ```bash
259
- # Build orchestrator only
260
- npm run orchestrator:build
261
-
262
- # Build plugin only
263
- npm run plugin:build
264
- ```
265
-
266
- ### Watch Mode (Development)
267
-
268
- ```bash
269
- # Orchestrator with hot reload
270
- npm run orchestrator:dev
271
-
272
- # Plugin with watch
273
- cd packages/serverless-plugin
274
- npm run dev
161
+ $ npx lss start --self-engine
162
+ 🚀 LSS Orchestrator started (PID: 12345)
163
+ 📊 Server: http://localhost:3100
164
+ 🔧 Self Engine: http://localhost:14566 (no Docker)
165
+ ✅ Service is running
275
166
  ```
276
167
 
277
- ## Testing
278
-
279
- LSS includes comprehensive integration tests covering CLI, Orchestrator API, and Plugin functionality.
280
-
281
- ### Quick Start
282
-
283
- ```bash
284
- # Run all tests
285
- npm test
168
+ The CLI runs the orchestrator detached, storing the PID in
169
+ `$TMPDIR/lss-orchestrator-{serverPort}.pid` and logs in
170
+ `$TMPDIR/lss-orchestrator-{serverPort}.log` (no suffix for the default port 3100;
171
+ under `stateDir` both move into that directory). The port-scoped paths let multiple
172
+ LSS instances coexist — one per project — without trampling each other.
286
173
 
287
- # Run with coverage
288
- npm run test:coverage
289
-
290
- # Run specific test suite
291
- npm run test:cli
292
- npm run test:orchestrator
293
- npm run test:plugin
294
-
295
- # Watch mode
296
- npm run test:watch
297
- ```
174
+ ## Configuration
298
175
 
299
- ### Using Test Runner Script
176
+ Create an `lss.config.json` in the directory where you run `lss start` (all keys
177
+ optional — [full reference](docs/CONFIGURATION.md)):
178
+
179
+ ```jsonc
180
+ {
181
+ "serverPort": 3100, // dashboard + API
182
+ "engine": "localstack", // "localstack" (default) | "self" (no Docker)
183
+ "selfEngine": { "port": 14566 }, // engine "self" settings — docs/SELF_ENGINE.md
184
+ "localstackPort": 4566,
185
+ "services": ["dynamodb", "sqs", "sns", "s3", "lambda", "events"],
186
+ "seedsDir": "./seeds", // DynamoDB fixtures ({tableName}.json)
187
+ "autoPackage": false, // run `sls package` on register when template is missing
188
+ "lambdaRuntime": { "enabled": true, "execution": "auto" },
189
+ "branding": { // dashboard look & feel (optional)
190
+ "title": "Acme Cloud",
191
+ "logo": "./assets/acme.svg",
192
+ "colors": { "brand-primary": "#e63946" }
193
+ }
194
+ }
195
+ ```
196
+
197
+ The most common environment overrides (env always wins over the file):
198
+ `LSS_DASHBOARD_PORT`, `LSS_ENGINE` (`localstack`/`self`), `LOCALSTACK_AUTH_TOKEN`,
199
+ `LSS_ENABLE_DYNAMO_PROXY`. Complete list: [docs/CONFIGURATION.md](docs/CONFIGURATION.md#environment-variables).
200
+
201
+ The self engine's default port sits **outside 4566–4599** on purpose: a real LocalStack
202
+ install intercepts that whole range on some hosts (Docker Desktop/WSL2). `--self-engine`
203
+ cannot be combined with the LocalStack-only flags (`--external`, `--pro`,
204
+ `--localstack-token`).
205
+
206
+ ### LocalStack: managed, external, Pro
207
+
208
+ By default LSS spins up its own container (`lss-localstack-<port>`, services
209
+ `dynamodb,sqs,sns,s3,lambda,events`, persistence volume, local Lambda executor). To point
210
+ at an already-running instance set `mode: "external"` or pass `--external`. Recent
211
+ LocalStack images (`>= 2026.5` community, all `pro`) require an auth token:
300
212
 
301
213
  ```bash
302
- # Run all integration tests
303
- ./run-tests.sh
304
-
305
- # Run specific suite
306
- ./run-tests.sh cli
307
- ./run-tests.sh orchestrator
308
- ./run-tests.sh plugin
309
-
310
- # Run with coverage
311
- ./run-tests.sh coverage
312
-
313
- # Watch mode
314
- ./run-tests.sh watch
214
+ export LOCALSTACK_AUTH_TOKEN=ls-xxxxxxxx
215
+ npx lss start # community image with token
216
+ npx lss start --pro # pro image (token required)
315
217
  ```
316
218
 
317
- ### Test Coverage
318
-
319
- The test suite validates:
219
+ Details (`mode`, `localstackEdition`, `localstackVersion`, `localstackImage`):
220
+ [docs/CONFIGURATION.md](docs/CONFIGURATION.md).
320
221
 
321
- **CLI Commands**
322
- - `npx lss start` - Orchestrator startup
323
- - `npx lss stop` - Graceful shutdown
324
- - `npx lss status` - Status reporting
325
- - `npx lss logs` - Log viewing
326
- - `npx lss help` - Help information
222
+ ## Dashboard
327
223
 
328
- **Orchestrator API**
329
- - Service registration
330
- - Resource provisioning (DynamoDB, SQS, SNS)
331
- - Lambda proxy creation
332
- - Event source mappings
333
- - Error handling
224
+ The Vue 3 dashboard at `http://localhost:3100` has seven tabs — **Overview** (health,
225
+ config snapshot), **Services** (status, start/stop, live logs, per-service resource
226
+ breakdown incl. EventBridge buses & rules), **Lambdas** (registry + invoke), **APIs**
227
+ (emulated HTTP routes), **Queues** (send/receive/purge, consumers), **S3** (objects,
228
+ upload/download), **DynamoDB** (items explorer, editor, TTL, seeds). A region selector
229
+ lets you inspect resources in any region.
334
230
 
335
- **Serverless Plugin**
336
- - CloudFormation parsing
337
- - Resource creation in LocalStack
338
- - Service lifecycle management
339
-
340
- See [tests/README.md](tests/README.md) for detailed test documentation.
341
-
342
- ## How It Works
343
- npm run orchestrator:dev
231
+ It can carry your team's identity via the `branding` config key: navbar title/subtitle,
232
+ logo and favicon (URL or a file next to `lss.config.json`), default theme, and any
233
+ [TreeUI](https://www.npmjs.com/package/@treeui/vue) color token per theme:
344
234
 
345
- # Plugin with watch
346
- cd packages/serverless-plugin
347
- npm run dev
235
+ ```jsonc
236
+ "branding": {
237
+ "title": "Acme Cloud",
238
+ "subtitle": "Sandbox local",
239
+ "logo": "./assets/acme.svg",
240
+ "defaultTheme": "light",
241
+ "colors": { "brand-primary": "#e63946", "brand-hover": "#c1121f" },
242
+ "themeColors": { "dark": { "bg-primary": "#0d1b2a" } }
243
+ }
348
244
  ```
349
245
 
350
246
  ## How It Works
351
247
 
352
- ### Part 1: Initialization & Service Registration
248
+ ### Registration & provisioning
353
249
 
354
250
  ```mermaid
355
251
  sequenceDiagram
356
252
  participant Dev as Developer
357
- participant CLI as LSS CLI
253
+ participant Plugin as serverless-lss<br/>(plugin)
358
254
  participant Orch as Orchestrator
359
- participant LS as LocalStack
360
- participant Plugin as Serverless Plugin
361
- participant SLS as Serverless Offline
362
-
363
- Note over Dev,SLS: 1. Start LSS Environment
364
- Dev->>CLI: npx lss start
365
- CLI->>Orch: Start orchestrator (port 3100)
366
- Orch->>LS: Start LocalStack container (port 4566)
367
- LS-->>Orch: Ready
368
- Orch-->>CLI: ✅ Running (PID saved)
369
- CLI-->>Dev: Dashboard: http://localhost:3100
370
-
371
- Note over Dev,SLS: 2. Register Microservice
255
+ participant Eng as Engine<br/>(self or LocalStack)
256
+
372
257
  Dev->>Plugin: sls package
373
- Plugin->>Plugin: Read CloudFormation template
374
258
  Plugin->>Orch: POST /api/services/register
375
- Note right of Plugin: Sends: service name,<br/>CFN template,<br/>invoke port
376
-
377
- Orch->>Orch: Parse CloudFormation
378
- Note right of Orch: Extract:<br/>- DynamoDB tables<br/>- SQS queues<br/>- SNS topics<br/>- Event Source Mappings
379
-
380
- Note over Orch,LS: 3. Provision Resources
381
- Orch->>LS: Create DynamoDB tables
382
- LS-->>Orch: Tables created
383
- Orch->>LS: Create SQS queues (+ DLQs)
384
- LS-->>Orch: Queues created
385
- Orch->>LS: Create SNS topics
386
- LS-->>Orch: Topics created
387
-
388
- Note over Orch,LS: 4. Create Lambda Proxies (on-demand)
389
- loop For each Event Source Mapping
390
- Orch->>Orch: Generate proxy Lambda code
391
- Note right of Orch: Proxy points to<br/>Serverless Offline
392
- Orch->>LS: Create Lambda proxy function
393
- LS-->>Orch: Proxy created
394
- Orch->>LS: Create Event Source Mapping
395
- Note right of Orch: SQS/DynamoDB/SNS → Lambda
396
- LS-->>Orch: Mapping active
397
- end
398
-
399
- Orch-->>Plugin: ✅ Service registered
400
- Plugin-->>Dev: ✅ Provisioned resources
401
-
402
- Note over Dev,SLS: 5. Start Application
403
- Dev->>SLS: serverless offline start
404
- Note right of SLS: Starts on port 3020<br/>Lambda invoke: 13020
405
- SLS-->>Dev: ✅ Handlers ready
259
+ Note right of Plugin: Sends: servicePath,<br/>apiPort, invokePort, region
260
+ Orch->>Orch: Read + parse CloudFormation template<br/>from servicePath/.serverless/
261
+ Orch->>Eng: Create tables, queues, topics,<br/>buckets, buses, rules
262
+ Orch->>Eng: Wire event source mappings<br/>(SQS/streams/S3/EventBridge Lambda)
263
+ Orch->>Orch: Start Lambda runtime worker<br/>+ API listener (30xx) + invoke listener (130xx)
264
+ Orch-->>Plugin: registered (N resources)
406
265
  ```
407
266
 
408
- ### Part 2: Event Processing Flow
267
+ The plugin itself only reports *where* the service lives — the orchestrator reads
268
+ `.serverless/cloudformation-template-update-stack.json` from that path (running
269
+ `sls package` generates it; `autoPackage: true` lets the orchestrator regenerate it
270
+ on demand).
271
+
272
+ ### Event flow
409
273
 
410
274
  ```mermaid
411
275
  sequenceDiagram
412
276
  participant App as Application
413
- participant SQS as SQS Queue<br/>(LocalStack)
414
- participant LS as LocalStack
415
- participant Proxy as Lambda Proxy<br/>(LocalStack)
416
- participant SLS as Serverless Offline
417
- participant Handler as Lambda Handler
418
-
419
- Note over App,Handler: Message Processing Flow
420
-
421
- App->>SQS: Send message to queue
422
- Note right of App: AWS SDK configured<br/>to LocalStack endpoint
423
- SQS-->>App: Message accepted
424
-
425
- Note over SQS,LS: Event Source Mapping Active
426
- LS->>SQS: Poll for messages (BatchSize: 1-10)
427
- SQS-->>LS: Return message(s)
428
-
429
- LS->>Proxy: Invoke Lambda proxy
430
- Note right of LS: Event with Records[]:<br/>- SQS message body<br/>- Attributes<br/>- Message ID
431
-
432
- Note over Proxy,SLS: Proxy Forwards to Serverless Offline
433
- Proxy->>Proxy: Transform event if needed
434
- Note right of Proxy: Ensure Records[] format
435
-
436
- Proxy->>SLS: HTTP POST /2015-03-31/functions/<br/>{functionName}/invocations
437
- Note right of Proxy: Headers:<br/>- Content-Type: application/json<br/>- X-Amz-Invocation-Type
438
-
439
- SLS->>Handler: Execute handler(event, context)
440
- Note right of Handler: Real business logic<br/>runs here
441
-
442
- alt Handler Success
443
- Handler-->>SLS: Return response
444
- SLS-->>Proxy: 200 OK + response body
445
- Proxy-->>LS: Success
446
- LS->>SQS: Delete message from queue
447
- else Handler Error
448
- Handler-->>SLS: Throw error
449
- SLS-->>Proxy: 500 Error
450
- Proxy-->>LS: Error
451
- LS->>SQS: Return to queue or send to DLQ
452
- Note right of SQS: Based on retry policy
277
+ participant Eng as Engine<br/>(SQS queue)
278
+ participant RT as LSS Lambda runtime
279
+ participant H as Your handler
280
+
281
+ App->>Eng: SendMessage (AWS SDK)
282
+ Eng->>RT: Event batch {Records: [...]}
283
+ Note over Eng,RT: self engine: in-process dispatch<br/>LocalStack: proxy Lambda → HTTP → invoke listener
284
+ RT->>H: handler(event, context)
285
+ alt success
286
+ H-->>RT: return
287
+ RT-->>Eng: ok → message deleted
288
+ else error
289
+ H-->>RT: throw
290
+ RT-->>Eng: fail redelivery / DLQ
453
291
  end
454
-
455
- Note over App,Handler: Processing Complete
456
292
  ```
457
293
 
458
- ### Detailed Explanation
459
-
460
- 1. **Service Registration**:
461
- - Developer runs `sls package` in their microservice
462
- - Plugin reads `.serverless/cloudformation-template-update-stack.json`
463
- - Plugin POSTs to orchestrator `/api/services/register` with service metadata
464
-
465
- 2. **Resource Provisioning**:
466
- - Orchestrator parses CloudFormation template
467
- - Extracts DynamoDB tables, SQS queues, SNS topics
468
- - Creates resources in LocalStack via AWS SDK
469
- - **Only creates Lambda proxies when Event Source Mappings exist**
470
- - Generates proxy code that forwards to serverless-offline invoke endpoint
471
- - Creates event source mappings (SQS/DynamoDB/SNS → Lambda)
472
-
473
- 3. **Event Flow**:
474
- - Message arrives in SQS queue
475
- - LocalStack polls queue via event source mapping
476
- - Lambda proxy is triggered automatically
477
- - Proxy transforms event and makes HTTP POST to serverless-offline
478
- - Real handler executes in serverless-offline process
479
- - Response returned through proxy chain
480
- - Message deleted from queue on success, or sent to DLQ on failure
481
-
482
- ## CLI Implementation Details
483
-
484
- The `npx lss` CLI is implemented in `/bin/cli.js` and provides:
294
+ The same flow applies to DynamoDB streams, S3 notifications and EventBridge targets.
295
+ In LocalStack mode the hop goes through a generated proxy Lambda inside the container;
296
+ in self-engine mode the dispatcher calls the runtime directly — no proxy, no polling.
485
297
 
486
- - **Background Process Management**: Uses `spawn` with `detached: true` to run orchestrator independently
487
- - **PID File**: Stores process ID in `/tmp/lss-orchestrator-{serverPort}.pid` (or `/tmp/lss-orchestrator.pid` when serverPort is the default 3100). The port-scoped path lets multiple LSS instances coexist — one per project without trampling each other.
488
- - **Log File**: Redirects stdout/stderr to `/tmp/lss-orchestrator-{serverPort}.log` (or `/tmp/lss-orchestrator.log` for the default port).
489
- - **Process Monitoring**: Checks if process is alive before starting/stopping
490
- - **Clean Shutdown**: Sends SIGTERM for graceful termination
491
-
492
- ### Files
493
-
494
- - **PID File**: `/tmp/lss-orchestrator-{serverPort}.pid`
495
- - **Log File**: `/tmp/lss-orchestrator-{serverPort}.log`
496
-
497
- ## Troubleshooting
498
-
499
- ### Check Logs
298
+ If you still want serverless-offline to own the ports for a service, disable the
299
+ LSS runtime globally or per service with `lambdaRuntime.enabled`/`serviceRuntime`.
500
300
 
501
- ```bash
502
- npx lss logs
301
+ ## Architecture
503
302
 
504
- # Or directly
505
- tail -f /tmp/lss-orchestrator.log
506
303
  ```
304
+ local-serverless-stack/
305
+ ├── bin/cli.js # CLI entry point (npx lss)
306
+ ├── src/
307
+ │ ├── server/ # Express API + orchestration
308
+ │ │ ├── routes/ # HTTP endpoints (/api/services, /api/queues, …)
309
+ │ │ ├── services/ # provisioner, registrar, packager, seeds, …
310
+ │ │ ├── engine/ # self engine (in-process AWS emulation)
311
+ │ │ ├── runtime/ # Lambda runtime + API Gateway emulation
312
+ │ │ └── dev/ # dev utilities (DynamoDB proxy)
313
+ │ ├── client/ # programmatic client (LssClient) — package entry point
314
+ │ └── ui/ # Vue 3 dashboard (npm workspace, @treeui/vue)
315
+ ├── packages/serverless-plugin/ # serverless-lss (published separately)
316
+ ├── docs/ # reference docs
317
+ ├── examples/ # runnable sample projects
318
+ └── tests/ # unit + integration suites
319
+ ```
320
+
321
+ - **CLI** (`bin/cli.js`): background process management (start/stop/status/logs/seed)
322
+ - **Server** (`src/server/`): Express API + engine orchestration; serves the built UI
323
+ - **Engine** (`src/server/engine/`): the AWS provider behind everything — in-process **self engine** (:14566, no Docker) or managed/external **LocalStack** (:4566)
324
+ - **Client** (`src/client/`): `LssClient` — the same API surface as the dashboard, from code
325
+ - **Plugin** (`packages/serverless-plugin/`): auto-registration on `sls package`
507
326
 
508
- ### Orchestrator Won't Start
327
+ ## Development
509
328
 
510
329
  ```bash
511
- # Check if already running
512
- npx lss status
513
-
514
- # Check if build is complete
515
- ls -la /workspaces/local-serverless-stack/dist/server/
516
- ls -la /workspaces/local-serverless-stack/dist/ui/
517
-
518
- # Rebuild if needed
519
- npm run build
330
+ git clone https://github.com/viserion77/local-serverless-stack.git
331
+ cd local-serverless-stack
332
+ npm run setup # install root + UI workspace deps
333
+ npm run dev # server (tsx watch) + UI (vite) concurrently
334
+ npm run build # ui + server + client + plugin
520
335
  ```
521
336
 
522
- ### Port Already in Use
337
+ Granular builds: `server:build`, `ui:build`, `client:build`, `plugin:build`.
523
338
 
524
- The orchestrator uses port 3100 by default. If this port is in use:
339
+ ### Testing
525
340
 
526
341
  ```bash
527
- # Find process using port 3100
528
- lsof -i :3100
529
-
530
- # Kill if needed
531
- kill -9 <PID>
342
+ npm test # unit suite (jest)
343
+ npm run test:coverage # with coverage (CI gate)
344
+ npm run test:watch # watch mode
345
+ npm run test:integration # boots a real orchestrator (Docker/LocalStack required)
346
+ npm run lint # eslint
347
+ npx jest tests/unit/services/config-manager.test.ts # a single suite
532
348
  ```
533
349
 
534
- ## Optional Features
535
-
536
- ### DynamoDB Proxy (Port 8000)
537
-
538
- The orchestrator includes an optional reverse proxy on port 8000 that forwards to LocalStack (4566).
350
+ ## Troubleshooting
539
351
 
540
- Enable with:
541
352
  ```bash
542
- ENABLE_DYNAMO_PROXY=true npm run server:dev
353
+ npx lss status # running? which ports?
354
+ npx lss logs # orchestrator log (also: $TMPDIR/lss-orchestrator*.log)
355
+ ls dist/server dist/ui # built? if not: npm run build
356
+ lsof -i :3100 # who owns the port?
543
357
  ```
544
358
 
545
- Located in: `src/server/dev/dynamo-proxy.ts`
546
-
547
- ## Project Status
548
-
549
- ⚠️ **Version 0.1.0 - Internal Development**
550
-
551
- This project is currently in active development and is being used internally. It is not yet published to npm.
552
-
553
- ### Completed Features
554
-
555
- - ✅ CLI with start/stop/status/logs commands
556
- - ✅ Background process management
557
- - ✅ Serverless Framework plugin
558
- - ✅ Auto-provisioning of AWS resources
559
- - ✅ Event source mapping (SQS → Lambda)
560
- - ✅ Web dashboard (Vue 3)
561
- - ✅ npm link support for local development
359
+ - **Plugin registers nothing** → is `orchestratorUrl` pointing at the right `serverPort`? Try `ORCHESTRATOR_URL=http://localhost:3100 npx sls package`.
360
+ - **Ports 4566–4599 behave strangely** → a real LocalStack install may intercept the whole range; the self engine defaults to 14566 for this reason.
361
+ - **DynamoDB on port 8000 expected by your tooling** → enable the proxy: `lss start --enable-dynamo-proxy` (or `enableDynamoProxy: true`); it forwards to the active engine.
562
362
 
563
- ## Use Case Example
363
+ ## Contributing & Releasing
564
364
 
565
- LSS can be used in monorepo setups to manage 15+ microservices with a single LocalStack instance. This eliminates the complexity of running multiple LocalStack containers and provides a unified development experience.
566
-
567
- Integration approach:
568
- - Place LSS in a dedicated directory (e.g., `/workspaces/local-serverless-stack`)
569
- - Use `npm link` for local development and seamless updates
570
- - Install the plugin in each microservice that needs AWS resource orchestration
571
- - Orchestrator managed via `npx lss start/stop` commands
572
-
573
- ## Contributing
574
-
575
- Contributions welcome! This is an open-source project designed to simplify local serverless development.
365
+ Contributions welcome see [CONTRIBUTING.md](CONTRIBUTING.md). Release process
366
+ (automated npm publish on version bump): [docs/RELEASE.md](docs/RELEASE.md).
367
+ Changelog: [CHANGELOG.md](CHANGELOG.md).
576
368
 
577
369
  ## License
578
370
 
579
371
  MIT
580
-
581
- ## Publishing to npm
582
-
583
- ⚠️ **For maintainers only**
584
-
585
- ### Automatic Publishing (Recommended)
586
-
587
- The project uses GitHub Actions for automatic publishing to NPM when you update the version:
588
-
589
- **1. Update version in package.json**:
590
- ```bash
591
- # For the root package (CLI + orchestrator)
592
- npm version patch # 0.0.1 -> 0.0.2
593
- npm version minor # 0.0.1 -> 0.1.0
594
- npm version major # 0.0.1 -> 1.0.0
595
- ```
596
-
597
- **2. Push to main branch**:
598
- ```bash
599
- git add package.json CHANGELOG.md
600
- git commit -m "chore: bump version to 0.0.2"
601
- git push origin main
602
- ```
603
-
604
- **3. GitHub Actions will automatically**:
605
- - ✅ Detect version change
606
- - ✅ Run full test suite
607
- - ✅ Build the project
608
- - ✅ Publish to NPM
609
- - ✅ Create a git tag (e.g., `v0.0.2`)
610
-
611
- ### Plugin Package
612
-
613
- To publish the serverless plugin separately:
614
-
615
- ```bash
616
- cd packages/serverless-plugin
617
- npm version patch
618
- cd ../..
619
- git add packages/serverless-plugin/package.json
620
- git commit -m "chore(plugin): bump version to 0.0.2"
621
- git push origin main
622
- ```
623
-
624
- ### Required Setup (One-time)
625
-
626
- Before automatic publishing works:
627
-
628
- 1. **NPM Access Token**:
629
- - Go to npmjs.com → Access Tokens → Generate New Token
630
- - Select "Automation" type
631
- - Copy the token
632
-
633
- 2. **GitHub Secret**:
634
- - Go to your repo → Settings → Secrets and variables → Actions
635
- - Add new repository secret: `NPM_TOKEN`
636
- - Paste your NPM token
637
-
638
- ### Pre-publish Checklist
639
-
640
- 1. ✅ All tests passing
641
- 2. ✅ Build successful (`npm run build`)
642
- 3. ✅ Version updated in `package.json`
643
- 4. ✅ CHANGELOG.md updated
644
- 5. ✅ README.md updated
645
- 6. ✅ No breaking changes (or properly documented)
646
-
647
- ### Manual Publishing (Emergency Only)
648
-
649
- If GitHub Actions fails, you can publish manually:
650
-
651
- ```bash
652
- # 1. Ensure clean working directory
653
- git status
654
-
655
- # 2. Build all packages
656
- npm run build
657
-
658
- # 3. Test the package contents
659
- npm pack
660
- tar -tzf local-serverless-stack-*.tgz
661
-
662
- # 4. Publish to npm (dry-run first)
663
- npm publish --dry-run
664
-
665
- # 5. Publish for real
666
- npm publish --access public
667
-
668
- # 6. Create git tag
669
- git tag v0.0.1
670
- git push origin v0.0.1
671
- ```
672
-
673
- ### What Gets Published
674
-
675
- The `files` field in package.json controls what's published:
676
-
677
- - `bin/` - CLI scripts
678
- - `dist/` - Compiled server + UI
679
- - `packages/serverless-plugin/dist/` - Compiled plugin
680
- - `README.md`, `LICENSE`, `CHANGELOG.md`
681
-
682
- Source files and development dependencies are **not** included.
683
-
684
- ### Post-publish
685
-
686
- After publishing, users can install with:
687
-
688
- ```bash
689
- npm install local-serverless-stack
690
- npx lss start
691
- ```
692
-
693
- No build step required for end users!