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.
- package/CHANGELOG.md +104 -0
- package/README.md +261 -583
- package/bin/cli.js +31 -3
- package/dist/client/types.d.ts +4 -0
- package/dist/client/types.d.ts.map +1 -1
- package/dist/server/engine/aoss-sidecar.d.ts +13 -0
- package/dist/server/engine/aoss-sidecar.d.ts.map +1 -0
- package/dist/server/engine/aoss-sidecar.js +93 -0
- package/dist/server/engine/aoss-sidecar.js.map +1 -0
- package/dist/server/engine/backends/localstack-backend.d.ts +25 -0
- package/dist/server/engine/backends/localstack-backend.d.ts.map +1 -0
- package/dist/server/engine/backends/localstack-backend.js +199 -0
- package/dist/server/engine/backends/localstack-backend.js.map +1 -0
- package/dist/server/engine/backends/self-backend.d.ts +32 -0
- package/dist/server/engine/backends/self-backend.d.ts.map +1 -0
- package/dist/server/engine/backends/self-backend.js +207 -0
- package/dist/server/engine/backends/self-backend.js.map +1 -0
- package/dist/server/engine/bus.d.ts +10 -0
- package/dist/server/engine/bus.d.ts.map +1 -0
- package/dist/server/engine/bus.js +24 -0
- package/dist/server/engine/bus.js.map +1 -0
- package/dist/server/engine/dispatch/dispatcher.d.ts +46 -0
- package/dist/server/engine/dispatch/dispatcher.d.ts.map +1 -0
- package/dist/server/engine/dispatch/dispatcher.js +312 -0
- package/dist/server/engine/dispatch/dispatcher.js.map +1 -0
- package/dist/server/engine/dispatch/scheduler.d.ts +47 -0
- package/dist/server/engine/dispatch/scheduler.d.ts.map +1 -0
- package/dist/server/engine/dispatch/scheduler.js +328 -0
- package/dist/server/engine/dispatch/scheduler.js.map +1 -0
- package/dist/server/engine/dispatch/sqs-poller.d.ts +25 -0
- package/dist/server/engine/dispatch/sqs-poller.d.ts.map +1 -0
- package/dist/server/engine/dispatch/sqs-poller.js +242 -0
- package/dist/server/engine/dispatch/sqs-poller.js.map +1 -0
- package/dist/server/engine/dispatch/stream-tailer.d.ts +22 -0
- package/dist/server/engine/dispatch/stream-tailer.d.ts.map +1 -0
- package/dist/server/engine/dispatch/stream-tailer.js +205 -0
- package/dist/server/engine/dispatch/stream-tailer.js.map +1 -0
- package/dist/server/engine/emulators/dynamodb/expressions/decimal.d.ts +5 -0
- package/dist/server/engine/emulators/dynamodb/expressions/decimal.d.ts.map +1 -0
- package/dist/server/engine/emulators/dynamodb/expressions/decimal.js +91 -0
- package/dist/server/engine/emulators/dynamodb/expressions/decimal.js.map +1 -0
- package/dist/server/engine/emulators/dynamodb/expressions/evaluate.d.ts +24 -0
- package/dist/server/engine/emulators/dynamodb/expressions/evaluate.d.ts.map +1 -0
- package/dist/server/engine/emulators/dynamodb/expressions/evaluate.js +183 -0
- package/dist/server/engine/emulators/dynamodb/expressions/evaluate.js.map +1 -0
- package/dist/server/engine/emulators/dynamodb/expressions/expression-types.d.ts +29 -0
- package/dist/server/engine/emulators/dynamodb/expressions/expression-types.d.ts.map +1 -0
- package/dist/server/engine/emulators/dynamodb/expressions/expression-types.js +12 -0
- package/dist/server/engine/emulators/dynamodb/expressions/expression-types.js.map +1 -0
- package/dist/server/engine/emulators/dynamodb/expressions/index.d.ts +13 -0
- package/dist/server/engine/emulators/dynamodb/expressions/index.d.ts.map +1 -0
- package/dist/server/engine/emulators/dynamodb/expressions/index.js +244 -0
- package/dist/server/engine/emulators/dynamodb/expressions/index.js.map +1 -0
- package/dist/server/engine/emulators/dynamodb/expressions/lexer.d.ts +11 -0
- package/dist/server/engine/emulators/dynamodb/expressions/lexer.d.ts.map +1 -0
- package/dist/server/engine/emulators/dynamodb/expressions/lexer.js +109 -0
- package/dist/server/engine/emulators/dynamodb/expressions/lexer.js.map +1 -0
- package/dist/server/engine/emulators/dynamodb/expressions/parser.d.ts +23 -0
- package/dist/server/engine/emulators/dynamodb/expressions/parser.d.ts.map +1 -0
- package/dist/server/engine/emulators/dynamodb/expressions/parser.js +541 -0
- package/dist/server/engine/emulators/dynamodb/expressions/parser.js.map +1 -0
- package/dist/server/engine/emulators/dynamodb/index.d.ts +46 -0
- package/dist/server/engine/emulators/dynamodb/index.d.ts.map +1 -0
- package/dist/server/engine/emulators/dynamodb/index.js +572 -0
- package/dist/server/engine/emulators/dynamodb/index.js.map +1 -0
- package/dist/server/engine/emulators/dynamodb/query.d.ts +12 -0
- package/dist/server/engine/emulators/dynamodb/query.d.ts.map +1 -0
- package/dist/server/engine/emulators/dynamodb/query.js +237 -0
- package/dist/server/engine/emulators/dynamodb/query.js.map +1 -0
- package/dist/server/engine/emulators/dynamodb/schema.d.ts +58 -0
- package/dist/server/engine/emulators/dynamodb/schema.d.ts.map +1 -0
- package/dist/server/engine/emulators/dynamodb/schema.js +284 -0
- package/dist/server/engine/emulators/dynamodb/schema.js.map +1 -0
- package/dist/server/engine/emulators/dynamodb/streams.d.ts +28 -0
- package/dist/server/engine/emulators/dynamodb/streams.d.ts.map +1 -0
- package/dist/server/engine/emulators/dynamodb/streams.js +100 -0
- package/dist/server/engine/emulators/dynamodb/streams.js.map +1 -0
- package/dist/server/engine/emulators/events/index.d.ts +53 -0
- package/dist/server/engine/emulators/events/index.d.ts.map +1 -0
- package/dist/server/engine/emulators/events/index.js +417 -0
- package/dist/server/engine/emulators/events/index.js.map +1 -0
- package/dist/server/engine/emulators/events/pattern.d.ts +3 -0
- package/dist/server/engine/emulators/events/pattern.d.ts.map +1 -0
- package/dist/server/engine/emulators/events/pattern.js +125 -0
- package/dist/server/engine/emulators/events/pattern.js.map +1 -0
- package/dist/server/engine/emulators/lambda-ctl/index.d.ts +55 -0
- package/dist/server/engine/emulators/lambda-ctl/index.d.ts.map +1 -0
- package/dist/server/engine/emulators/lambda-ctl/index.js +461 -0
- package/dist/server/engine/emulators/lambda-ctl/index.js.map +1 -0
- package/dist/server/engine/emulators/opensearch/index.d.ts +67 -0
- package/dist/server/engine/emulators/opensearch/index.d.ts.map +1 -0
- package/dist/server/engine/emulators/opensearch/index.js +811 -0
- package/dist/server/engine/emulators/opensearch/index.js.map +1 -0
- package/dist/server/engine/emulators/opensearch/search.d.ts +17 -0
- package/dist/server/engine/emulators/opensearch/search.d.ts.map +1 -0
- package/dist/server/engine/emulators/opensearch/search.js +434 -0
- package/dist/server/engine/emulators/opensearch/search.js.map +1 -0
- package/dist/server/engine/emulators/s3/index.d.ts +45 -0
- package/dist/server/engine/emulators/s3/index.d.ts.map +1 -0
- package/dist/server/engine/emulators/s3/index.js +591 -0
- package/dist/server/engine/emulators/s3/index.js.map +1 -0
- package/dist/server/engine/emulators/sns/index.d.ts +22 -0
- package/dist/server/engine/emulators/sns/index.d.ts.map +1 -0
- package/dist/server/engine/emulators/sns/index.js +135 -0
- package/dist/server/engine/emulators/sns/index.js.map +1 -0
- package/dist/server/engine/emulators/sqs/index.d.ts +66 -0
- package/dist/server/engine/emulators/sqs/index.d.ts.map +1 -0
- package/dist/server/engine/emulators/sqs/index.js +552 -0
- package/dist/server/engine/emulators/sqs/index.js.map +1 -0
- package/dist/server/engine/emulators/sqs/md5.d.ts +8 -0
- package/dist/server/engine/emulators/sqs/md5.d.ts.map +1 -0
- package/dist/server/engine/emulators/sqs/md5.js +36 -0
- package/dist/server/engine/emulators/sqs/md5.js.map +1 -0
- package/dist/server/engine/emulators/sqs/queue.d.ts +105 -0
- package/dist/server/engine/emulators/sqs/queue.d.ts.map +1 -0
- package/dist/server/engine/emulators/sqs/queue.js +371 -0
- package/dist/server/engine/emulators/sqs/queue.js.map +1 -0
- package/dist/server/engine/emulators/sts.d.ts +8 -0
- package/dist/server/engine/emulators/sts.d.ts.map +1 -0
- package/dist/server/engine/emulators/sts.js +23 -0
- package/dist/server/engine/emulators/sts.js.map +1 -0
- package/dist/server/engine/engine-backend.d.ts +17 -0
- package/dist/server/engine/engine-backend.d.ts.map +1 -0
- package/dist/server/engine/engine-backend.js +7 -0
- package/dist/server/engine/engine-backend.js.map +1 -0
- package/dist/server/engine/engine-manager.d.ts +22 -0
- package/dist/server/engine/engine-manager.d.ts.map +1 -0
- package/dist/server/engine/engine-manager.js +74 -0
- package/dist/server/engine/engine-manager.js.map +1 -0
- package/dist/server/engine/http/aws-chunked.d.ts +3 -0
- package/dist/server/engine/http/aws-chunked.d.ts.map +1 -0
- package/dist/server/engine/http/aws-chunked.js +50 -0
- package/dist/server/engine/http/aws-chunked.js.map +1 -0
- package/dist/server/engine/http/errors.d.ts +20 -0
- package/dist/server/engine/http/errors.d.ts.map +1 -0
- package/dist/server/engine/http/errors.js +43 -0
- package/dist/server/engine/http/errors.js.map +1 -0
- package/dist/server/engine/http/protocols/aws-json.d.ts +8 -0
- package/dist/server/engine/http/protocols/aws-json.d.ts.map +1 -0
- package/dist/server/engine/http/protocols/aws-json.js +42 -0
- package/dist/server/engine/http/protocols/aws-json.js.map +1 -0
- package/dist/server/engine/http/protocols/query-xml.d.ts +7 -0
- package/dist/server/engine/http/protocols/query-xml.d.ts.map +1 -0
- package/dist/server/engine/http/protocols/query-xml.js +35 -0
- package/dist/server/engine/http/protocols/query-xml.js.map +1 -0
- package/dist/server/engine/http/router.d.ts +8 -0
- package/dist/server/engine/http/router.d.ts.map +1 -0
- package/dist/server/engine/http/router.js +402 -0
- package/dist/server/engine/http/router.js.map +1 -0
- package/dist/server/engine/http/sigv4.d.ts +9 -0
- package/dist/server/engine/http/sigv4.d.ts.map +1 -0
- package/dist/server/engine/http/sigv4.js +33 -0
- package/dist/server/engine/http/sigv4.js.map +1 -0
- package/dist/server/engine/http/xml.d.ts +16 -0
- package/dist/server/engine/http/xml.d.ts.map +1 -0
- package/dist/server/engine/http/xml.js +92 -0
- package/dist/server/engine/http/xml.js.map +1 -0
- package/dist/server/engine/store/atomic.d.ts +4 -0
- package/dist/server/engine/store/atomic.d.ts.map +1 -0
- package/dist/server/engine/store/atomic.js +35 -0
- package/dist/server/engine/store/atomic.js.map +1 -0
- package/dist/server/engine/store/engine-store.d.ts +9 -0
- package/dist/server/engine/store/engine-store.d.ts.map +1 -0
- package/dist/server/engine/store/engine-store.js +218 -0
- package/dist/server/engine/store/engine-store.js.map +1 -0
- package/dist/server/engine/store/store-types.d.ts +37 -0
- package/dist/server/engine/store/store-types.d.ts.map +1 -0
- package/dist/server/engine/store/store-types.js +17 -0
- package/dist/server/engine/store/store-types.js.map +1 -0
- package/dist/server/engine/store/wal.d.ts +49 -0
- package/dist/server/engine/store/wal.d.ts.map +1 -0
- package/dist/server/engine/store/wal.js +328 -0
- package/dist/server/engine/store/wal.js.map +1 -0
- package/dist/server/engine/types.d.ts +137 -0
- package/dist/server/engine/types.d.ts.map +1 -0
- package/dist/server/engine/types.js +8 -0
- package/dist/server/engine/types.js.map +1 -0
- package/dist/server/index.js +43 -9
- package/dist/server/index.js.map +1 -1
- package/dist/server/routes/config.d.ts.map +1 -1
- package/dist/server/routes/config.js +16 -0
- package/dist/server/routes/config.js.map +1 -1
- package/dist/server/routes/opensearch.d.ts +3 -0
- package/dist/server/routes/opensearch.d.ts.map +1 -0
- package/dist/server/routes/opensearch.js +69 -0
- package/dist/server/routes/opensearch.js.map +1 -0
- package/dist/server/routes/resources.d.ts.map +1 -1
- package/dist/server/routes/resources.js +4 -1
- package/dist/server/routes/resources.js.map +1 -1
- package/dist/server/routes/services.d.ts.map +1 -1
- package/dist/server/routes/services.js +3 -0
- package/dist/server/routes/services.js.map +1 -1
- package/dist/server/services/cache-manager.d.ts +2 -1
- package/dist/server/services/cache-manager.d.ts.map +1 -1
- package/dist/server/services/cache-manager.js +22 -2
- package/dist/server/services/cache-manager.js.map +1 -1
- package/dist/server/services/cloudformation-parser.d.ts +35 -2
- package/dist/server/services/cloudformation-parser.d.ts.map +1 -1
- package/dist/server/services/cloudformation-parser.js +88 -3
- package/dist/server/services/cloudformation-parser.js.map +1 -1
- package/dist/server/services/config-manager.d.ts +82 -0
- package/dist/server/services/config-manager.d.ts.map +1 -1
- package/dist/server/services/config-manager.js +151 -7
- package/dist/server/services/config-manager.js.map +1 -1
- package/dist/server/services/gateway-manager.d.ts +2 -0
- package/dist/server/services/gateway-manager.d.ts.map +1 -1
- package/dist/server/services/gateway-manager.js +44 -6
- package/dist/server/services/gateway-manager.js.map +1 -1
- package/dist/server/services/localstack-manager.d.ts +0 -7
- package/dist/server/services/localstack-manager.d.ts.map +1 -1
- package/dist/server/services/localstack-manager.js +11 -173
- package/dist/server/services/localstack-manager.js.map +1 -1
- package/dist/server/services/opensearch-explorer.d.ts +37 -0
- package/dist/server/services/opensearch-explorer.d.ts.map +1 -0
- package/dist/server/services/opensearch-explorer.js +124 -0
- package/dist/server/services/opensearch-explorer.js.map +1 -0
- package/dist/server/services/resource-provisioner.d.ts +13 -0
- package/dist/server/services/resource-provisioner.d.ts.map +1 -1
- package/dist/server/services/resource-provisioner.js +257 -11
- package/dist/server/services/resource-provisioner.js.map +1 -1
- package/dist/server/services/service-registrar.d.ts +1 -0
- package/dist/server/services/service-registrar.d.ts.map +1 -1
- package/dist/server/services/service-registrar.js +19 -4
- package/dist/server/services/service-registrar.js.map +1 -1
- package/dist/ui/assets/ApisPage-C0xaNFQW.js +1 -0
- package/dist/ui/assets/BucketDetailPage-Bnny8S04.js +1 -0
- package/dist/ui/assets/BucketsPage-Dd3Y4-gU.js +1 -0
- package/dist/ui/assets/{DynamoPage-B1__Rjr2.js → DynamoPage-JzSF-4VI.js} +1 -1
- package/dist/ui/assets/DynamoTablePage-uM0DXGCo.js +3 -0
- package/dist/ui/assets/LambdaDetailPage-CoR9ZXdb.js +4 -0
- package/dist/ui/assets/LambdasPage-CNMX_O5P.js +1 -0
- package/dist/ui/assets/OpenSearchCollectionPage-D5FaSCF1.js +1 -0
- package/dist/ui/assets/OpenSearchPage-FEzLxaej.js +1 -0
- package/dist/ui/assets/OverviewPage-0xvjT7Q0.js +1 -0
- package/dist/ui/assets/OverviewPage-qEl0a-0B.css +1 -0
- package/dist/ui/assets/QueueDetailPage-B2GaNLLe.js +1 -0
- package/dist/ui/assets/QueuesPage-Ch5kGwrp.js +1 -0
- package/dist/ui/assets/ServiceDetailPage-DKiz21oo.js +2 -0
- package/dist/ui/assets/ServicesPage-Cmi3UIfM.js +2 -0
- package/dist/ui/assets/index-DH7RTkRh.css +1 -0
- package/dist/ui/assets/index-MF9fVrsr.js +37 -0
- package/dist/ui/index.html +2 -2
- package/package.json +3 -1
- package/dist/ui/assets/ApisPage-DdgKjEdS.js +0 -1
- package/dist/ui/assets/BucketDetailPage-DZQGxm0y.js +0 -1
- package/dist/ui/assets/BucketsPage-xYXzxCvd.js +0 -1
- package/dist/ui/assets/DynamoTablePage-BCoxPdXW.js +0 -3
- package/dist/ui/assets/LambdaDetailPage-B85CA8tb.js +0 -4
- package/dist/ui/assets/LambdasPage-_TtxQMT_.js +0 -1
- package/dist/ui/assets/OverviewPage-6jDXV1jr.css +0 -1
- package/dist/ui/assets/OverviewPage-CqTKTY64.js +0 -1
- package/dist/ui/assets/QueueDetailPage-BOr_sImA.js +0 -1
- package/dist/ui/assets/QueuesPage-DpByfcM5.js +0 -1
- package/dist/ui/assets/ServiceDetailPage-DsWgV-ad.js +0 -2
- package/dist/ui/assets/ServicesPage-CGlpsj98.js +0 -2
- package/dist/ui/assets/index-BWlB542w.js +0 -36
- package/dist/ui/assets/index-EYnsoJOq.css +0 -1
package/README.md
CHANGED
|
@@ -2,692 +2,370 @@
|
|
|
2
2
|
|
|
3
3
|
[](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
|
|
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
|
-
-
|
|
12
|
-
- **
|
|
13
|
-
- **Event source mappings**: Automatically connects SQS queues, streams,
|
|
14
|
-
- **Lambda runtime & API emulation**: LSS
|
|
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
|
-
- **
|
|
18
|
-
- **CLI
|
|
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
|
-
##
|
|
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
|
-
|
|
75
|
-
|
|
76
|
-
|
|
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
|
-
|
|
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
|
-
|
|
49
|
+
What you get:
|
|
123
50
|
|
|
124
|
-
|
|
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
|
-
```
|
|
127
|
-
|
|
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
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
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
|
-
|
|
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
|
-
|
|
91
|
+
## Quick Start
|
|
139
92
|
|
|
140
|
-
|
|
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
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
### 2. Install Plugin in Microservices
|
|
96
|
+
# 1. Install
|
|
97
|
+
npm install -g local-serverless-stack
|
|
147
98
|
|
|
148
|
-
|
|
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
|
-
|
|
151
|
-
npm
|
|
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-
|
|
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
|
-
|
|
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
|
-
#
|
|
175
|
-
|
|
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
|
-
#
|
|
125
|
+
# 5. Watch everything in the dashboard
|
|
182
126
|
open http://localhost:3100
|
|
183
127
|
```
|
|
184
128
|
|
|
185
|
-
|
|
186
|
-
|
|
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
|
-
|
|
192
|
-
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
242
|
-
|
|
243
|
-
|
|
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
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
303
|
-
|
|
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
|
-
|
|
318
|
-
|
|
319
|
-
The test suite validates:
|
|
219
|
+
Details (`mode`, `localstackEdition`, `localstackVersion`, `localstackImage`):
|
|
220
|
+
[docs/CONFIGURATION.md](docs/CONFIGURATION.md).
|
|
320
221
|
|
|
321
|
-
|
|
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
|
-
|
|
329
|
-
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
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
|
-
|
|
336
|
-
|
|
337
|
-
|
|
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
|
-
|
|
346
|
-
|
|
347
|
-
|
|
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
|
-
###
|
|
248
|
+
### Registration & provisioning
|
|
353
249
|
|
|
354
250
|
```mermaid
|
|
355
251
|
sequenceDiagram
|
|
356
252
|
participant Dev as Developer
|
|
357
|
-
participant
|
|
253
|
+
participant Plugin as serverless-lss<br/>(plugin)
|
|
358
254
|
participant Orch as Orchestrator
|
|
359
|
-
participant
|
|
360
|
-
|
|
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:
|
|
376
|
-
|
|
377
|
-
Orch->>
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
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
|
-
|
|
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
|
|
414
|
-
participant
|
|
415
|
-
participant
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
Note over
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
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
|
-
|
|
459
|
-
|
|
460
|
-
|
|
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
|
-
|
|
487
|
-
|
|
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
|
-
|
|
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
|
-
|
|
327
|
+
## Development
|
|
509
328
|
|
|
510
329
|
```bash
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
#
|
|
515
|
-
|
|
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
|
-
|
|
337
|
+
Granular builds: `server:build`, `ui:build`, `client:build`, `plugin:build`.
|
|
523
338
|
|
|
524
|
-
|
|
339
|
+
### Testing
|
|
525
340
|
|
|
526
341
|
```bash
|
|
527
|
-
#
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
#
|
|
531
|
-
|
|
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
|
-
##
|
|
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
|
-
|
|
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
|
-
|
|
546
|
-
|
|
547
|
-
|
|
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
|
-
##
|
|
363
|
+
## Contributing & Releasing
|
|
564
364
|
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
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!
|