@vyckr/tachyon 0.3.0 → 1.0.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/.env.example +3 -17
- package/README.md +87 -57
- package/bun.lock +127 -0
- package/components/counter.html +13 -0
- package/deno.lock +19 -0
- package/go.mod +3 -0
- package/lib/gson-2.3.jar +0 -0
- package/main.js +0 -0
- package/package.json +19 -20
- package/routes/DELETE +18 -0
- package/routes/GET +17 -0
- package/routes/HTML +28 -0
- package/routes/POST +32 -0
- package/routes/SOCKET +26 -0
- package/routes/api/:version/DELETE +10 -0
- package/routes/api/:version/GET +29 -0
- package/routes/api/:version/PATCH +24 -0
- package/routes/api/GET +29 -0
- package/routes/api/POST +16 -0
- package/routes/api/PUT +21 -0
- package/src/client/404.html +7 -0
- package/src/client/dev.html +14 -0
- package/src/client/dist.ts +20 -0
- package/src/client/hmr.js +12 -0
- package/src/client/prod.html +13 -0
- package/src/client/render.js +278 -0
- package/src/client/routes.json +1 -0
- package/src/client/yon.ts +341 -0
- package/src/router.ts +185 -0
- package/src/serve.ts +144 -0
- package/src/server/logger.ts +31 -0
- package/src/server/tach.ts +234 -0
- package/tests/index.test.ts +110 -0
- package/tests/stream.ts +24 -0
- package/tests/worker.ts +7 -0
- package/tsconfig.json +1 -1
- package/Dockerfile +0 -47
- package/bun.lockb +0 -0
- package/routes/byos/[primary]/doc/index.ts +0 -28
- package/routes/byos/[primary]/docs/index.ts +0 -28
- package/routes/byos/[primary]/join/[secondary]/docs/index.ts +0 -10
- package/routes/byos/[primary]/schema/index.ts +0 -17
- package/routes/byos/[primary]/stream/doc/index.ts +0 -28
- package/routes/byos/[primary]/stream/docs/index.ts +0 -28
- package/routes/proxy.ts +0 -8
- package/routes/utils/validation.ts +0 -36
- package/src/Tach.ts +0 -543
- package/src/Yon.ts +0 -25
- package/src/runtime.ts +0 -822
- package/types/index.d.ts +0 -13
package/.env.example
CHANGED
|
@@ -1,24 +1,10 @@
|
|
|
1
1
|
# Tachyon environment variables
|
|
2
2
|
PORT=8000
|
|
3
|
+
NODE_ENV=development|production
|
|
4
|
+
HOSTNAME=127.0.0.1
|
|
3
5
|
ALLOW_HEADERS=*
|
|
4
6
|
ALLOW_ORGINS=*
|
|
5
7
|
ALLOW_CREDENTIALS=true|false
|
|
6
8
|
ALLOW_EXPOSE_HEADERS=*
|
|
7
9
|
ALLOW_MAX_AGE=3600
|
|
8
|
-
ALLOW_METHODS=GET,POST,PUT,DELETE,PATCH
|
|
9
|
-
PRODUCTION=true|false
|
|
10
|
-
SAVE_LOGS=true|false
|
|
11
|
-
SAVE_STATS=true|false
|
|
12
|
-
SAVE_REQUESTS=true|false
|
|
13
|
-
SAVE_ERRORS=true|false
|
|
14
|
-
|
|
15
|
-
# BYOS environment variables
|
|
16
|
-
DB_DIR=/path/to/disk/database
|
|
17
|
-
SCHEMA=LOOSE|STRICT
|
|
18
|
-
LOGGING=true|false
|
|
19
|
-
SCHEMA_PATH=/path/to/schema/directory
|
|
20
|
-
MEM_DR=/path/to/memory/database
|
|
21
|
-
S3_REGION=region
|
|
22
|
-
S3_INDEX_BUCKET=bucket
|
|
23
|
-
S3_DATA_BUCKET=bucket
|
|
24
|
-
S3_ENDPOINT=https//example.com
|
|
10
|
+
ALLOW_METHODS=GET,POST,PUT,DELETE,PATCH,OPTIONS
|
package/README.md
CHANGED
|
@@ -1,17 +1,13 @@
|
|
|
1
1
|
# Tachyon
|
|
2
2
|
|
|
3
|
-
Tachyon is a simple to use API framework built with TypeScript (Bun)
|
|
3
|
+
Tachyon is a simple to use API framework built with TypeScript (Bun). Tachyon aim to provide a simple and intuitive API framework for building serverless applications and abstracts away the complexity of configuations, letting you focus on building your application.
|
|
4
4
|
|
|
5
5
|
## Features
|
|
6
6
|
|
|
7
|
-
- Has BYOS [(Bring Your Own Storage)](https://github.com/Chidelma/BYOS) integration
|
|
8
|
-
- Use of decorators for routes
|
|
9
7
|
- Customizable methods for routes
|
|
10
|
-
- AWS Lambda support [(Docker)](https://hub.docker.com/repository/docker/iyormobi/tachyon/general)
|
|
11
8
|
- Use of file-system based routing
|
|
12
9
|
- Hot reloading of routes in development mode
|
|
13
10
|
- Supports dynamic routes
|
|
14
|
-
- Supports Async Iterators (Streaming)
|
|
15
11
|
|
|
16
12
|
## Installation
|
|
17
13
|
|
|
@@ -25,76 +21,104 @@ The .env file should be in the root directory of your project. The following env
|
|
|
25
21
|
```
|
|
26
22
|
# Tachyon environment variables
|
|
27
23
|
PORT=8000 (optional)
|
|
24
|
+
NODE_ENV=development|production (optional)
|
|
25
|
+
HOSTNAME=127.0.0.1 (optional)
|
|
28
26
|
ALLOW_HEADERS=* (optional)
|
|
29
27
|
ALLOW_ORGINS=* (optional)
|
|
30
28
|
ALLOW_CREDENTIALS=true|false (optional)
|
|
31
29
|
ALLOW_EXPOSE_HEADERS=* (optional)
|
|
32
30
|
ALLOW_MAX_AGE=3600 (optional)
|
|
33
31
|
ALLOW_METHODS=GET,POST,PUT,DELETE,PATCH (optional)
|
|
34
|
-
PRODUCTION=true|false (optional)
|
|
35
|
-
SAVE_LOGS=true|false (optional)
|
|
36
|
-
SAVE_STATS=true|false (optional)
|
|
37
|
-
SAVE_REQUESTS=true|false (optional)
|
|
38
|
-
SAVE_ERRORS=true|false (optional)
|
|
39
|
-
|
|
40
|
-
# BYOS environment variables
|
|
41
|
-
DB_DIR=/path/to/disk/database (required)
|
|
42
|
-
SCHEMA=LOOSE|STRICT (optional)
|
|
43
|
-
LOGGING=true|false (optional)
|
|
44
|
-
SCHEMA_PATH=/path/to/schema/directory (required if SCHEMA is set to STRICT)
|
|
45
|
-
MEM_DR=/path/to/memory/database (optional)
|
|
46
|
-
S3_REGION=region (optional)
|
|
47
|
-
S3_INDEX_BUCKET=bucket (required)
|
|
48
|
-
S3_DATA_BUCKET=bucket (required)
|
|
49
|
-
S3_ENDPOINT=https//example.com (optional)
|
|
50
32
|
```
|
|
51
33
|
|
|
52
|
-
|
|
34
|
+
### Requirements
|
|
35
|
+
- Make sure to have a 'routes' directory in the root of your project
|
|
36
|
+
- Dynamic routes should start with a colon `:`
|
|
37
|
+
- The first parameter should NOT be a dynamic route (e.g. /:version/doc/GET)
|
|
38
|
+
- All dynamic routes should be within odd indexes (e.g. /v1/:path/login/:id/POST)
|
|
39
|
+
- The last parameter in the route should always be a capitalized method as a file name without file extension (e.g. /v1/:path/login/:id/name/DELETE)
|
|
40
|
+
- Front-end Pages end with capitalized `HTML` filename (e.g. /v1/HTML)
|
|
41
|
+
- Node modules should be imported dynamically with `modules` prefix (e.g. const { default: dayjs } = await import(`/modules/dayjs.js`))
|
|
42
|
+
- Components should be in the `components` folder and end with `.html` extension (e.g. /components/counter.html)
|
|
43
|
+
- First line of the file should be a shebang for the executable file (e.g. #!/usr/bin/env python3)
|
|
44
|
+
- Request context can be retrieved by extracting the last element in args and parsing it.
|
|
45
|
+
- Response of executable script must be in a String format and must written to the `/tmp` folder with the the process ID as the file name (e.g. `/tmp/1234`).
|
|
46
|
+
- Use the exit method of the executable script with a status code to end the process of the executable script
|
|
53
47
|
|
|
54
|
-
|
|
48
|
+
### Examples
|
|
55
49
|
|
|
50
|
+
|
|
51
|
+
```html
|
|
52
|
+
<!-- /routes/HTML -->
|
|
53
|
+
<script>
|
|
54
|
+
// top-level await
|
|
55
|
+
const { default: dayjs } = await import("/modules/dayjs.js")
|
|
56
|
+
|
|
57
|
+
console.log(dayjs().format())
|
|
58
|
+
|
|
59
|
+
const greeting = "Hello World!"
|
|
60
|
+
</script>
|
|
61
|
+
|
|
62
|
+
<p>${greeting}</p>
|
|
56
63
|
```
|
|
57
|
-
/path/to/schema/directory
|
|
58
|
-
/users.d.ts
|
|
59
|
-
```
|
|
60
|
-
### Requirements
|
|
61
|
-
- Make sure to have a 'routes' directory in the root of your project
|
|
62
|
-
- Dynamic routes should be enclosed in square brackets
|
|
63
|
-
- The first parameter should NOT be a dynamic route (e.g. /[version]/doc/index.ts)
|
|
64
|
-
- All dynamic routes should be within odd indexes (e.g. /v1/[path]/login/[id]/name/index.ts)
|
|
65
|
-
- The last parameter in the route should not be a dynamic route (e.g. /v1/[path]/login/[id]/name/index.ts)
|
|
66
64
|
|
|
67
65
|
```typescript
|
|
68
|
-
// routes/v1
|
|
69
|
-
|
|
70
|
-
|
|
66
|
+
// routes/v1/:collection/GET
|
|
67
|
+
|
|
68
|
+
#!/usr/bin/env bun
|
|
71
69
|
|
|
72
|
-
|
|
70
|
+
for await(const chunk of Bun.stdin.stream()) {
|
|
73
71
|
|
|
74
|
-
|
|
72
|
+
console.log("Executing Bun....");
|
|
75
73
|
|
|
76
|
-
|
|
77
|
-
async GET({ slugs }) {
|
|
78
|
-
return await Silo.findDocs(slugs.get(this.collection), { $limit: 10 })
|
|
79
|
-
}
|
|
74
|
+
const data = new TextDecoder().decode(chunk)
|
|
80
75
|
|
|
81
|
-
|
|
82
|
-
async POST(user: _user, { slugs }) {
|
|
83
|
-
return await Silo.putData(slugs.get(this.collection), { name: user.name, age: user.age })
|
|
84
|
-
}
|
|
76
|
+
const ctx = JSON.parse(data)
|
|
85
77
|
|
|
86
|
-
|
|
87
|
-
async PATCH(user: _user, { slugs }) {
|
|
88
|
-
return await Silo.patchDoc(slugs.get(this.collection), { $set: { name: user.name, age: user.age } })
|
|
89
|
-
}
|
|
78
|
+
ctx.message = "Hello from Bun!"
|
|
90
79
|
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
}
|
|
80
|
+
const response = JSON.stringify(ctx)
|
|
81
|
+
|
|
82
|
+
await Bun.write(`/tmp/${process.pid}`, response)
|
|
95
83
|
}
|
|
96
84
|
```
|
|
97
85
|
|
|
86
|
+
```python
|
|
87
|
+
# routes/v1/:collection/POST
|
|
88
|
+
|
|
89
|
+
#!/usr/bin/env python3
|
|
90
|
+
import json
|
|
91
|
+
import sys
|
|
92
|
+
import os
|
|
93
|
+
|
|
94
|
+
print("Executing Python....")
|
|
95
|
+
|
|
96
|
+
ctx = json.loads(sys.stdin.read())
|
|
97
|
+
|
|
98
|
+
ctx["message"] = "Hello from Python!"
|
|
99
|
+
|
|
100
|
+
file = open(f"/tmp/{os.getpid()}", "w")
|
|
101
|
+
|
|
102
|
+
file.write(json.dumps(ctx))
|
|
103
|
+
|
|
104
|
+
file.close()
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
```ruby
|
|
108
|
+
# routes/v1/:collection/DELETE
|
|
109
|
+
|
|
110
|
+
#!/usr/bin/env ruby
|
|
111
|
+
require 'json'
|
|
112
|
+
|
|
113
|
+
puts "Executing Ruby...."
|
|
114
|
+
|
|
115
|
+
ctx = JSON.parse(ARGF.read)
|
|
116
|
+
|
|
117
|
+
ctx["message"] = "Hello from Ruby!"
|
|
118
|
+
|
|
119
|
+
File.write("/tmp/#{Process.pid}", JSON.unparse(ctx))
|
|
120
|
+
```
|
|
121
|
+
|
|
98
122
|
To run the application, you can use the following command:
|
|
99
123
|
|
|
100
124
|
```bash
|
|
@@ -104,19 +128,25 @@ bun tach
|
|
|
104
128
|
To invoke the API endpoints, you can use the following commands:
|
|
105
129
|
|
|
106
130
|
```bash
|
|
107
|
-
curl -X GET http://localhost:8000/v1/users
|
|
131
|
+
curl -X GET http://localhost:8000/v1/users
|
|
108
132
|
```
|
|
109
133
|
|
|
110
134
|
```bash
|
|
111
|
-
curl -X POST http://localhost:8000/v1/users
|
|
135
|
+
curl -X POST http://localhost:8000/v1/users -d '{"name": "John Doe", "age": 30}'
|
|
112
136
|
```
|
|
113
137
|
|
|
114
138
|
```bash
|
|
115
|
-
curl -X PATCH http://localhost:8000/v1/users
|
|
139
|
+
curl -X PATCH http://localhost:8000/v1/users -d '{"name": "Jane Doe", "age": 31}'
|
|
116
140
|
```
|
|
117
141
|
|
|
118
142
|
```bash
|
|
119
|
-
curl -X DELETE http://localhost:8000/v1/users/
|
|
143
|
+
curl -X DELETE http://localhost:8000/v1/users/5e8b0a9c-c0d1-4d3b-a0b1-e2d8e0e9a1c0
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
To to build front-end assets into a `dist` folder, use the following command:
|
|
147
|
+
|
|
148
|
+
```bash
|
|
149
|
+
bun yon
|
|
120
150
|
```
|
|
121
151
|
|
|
122
152
|
# License
|
package/bun.lock
ADDED
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
{
|
|
2
|
+
"lockfileVersion": 1,
|
|
3
|
+
"workspaces": {
|
|
4
|
+
"": {
|
|
5
|
+
"name": "@vyckr/tachyon",
|
|
6
|
+
"dependencies": {
|
|
7
|
+
"dayjs": "^1.11.13",
|
|
8
|
+
"jsdom": "^26.0.0",
|
|
9
|
+
},
|
|
10
|
+
"devDependencies": {
|
|
11
|
+
"@types/bun": "^1.2.4",
|
|
12
|
+
"@types/deno": "^2.0.0",
|
|
13
|
+
"@types/jsdom": "^21.1.7",
|
|
14
|
+
"@types/node": "^20.4.2",
|
|
15
|
+
},
|
|
16
|
+
},
|
|
17
|
+
},
|
|
18
|
+
"packages": {
|
|
19
|
+
"@asamuzakjp/css-color": ["@asamuzakjp/css-color@2.8.3", "", { "dependencies": { "@csstools/css-calc": "^2.1.1", "@csstools/css-color-parser": "^3.0.7", "@csstools/css-parser-algorithms": "^3.0.4", "@csstools/css-tokenizer": "^3.0.3", "lru-cache": "^10.4.3" } }, "sha512-GIc76d9UI1hCvOATjZPyHFmE5qhRccp3/zGfMPapK3jBi+yocEzp6BBB0UnfRYP9NP4FANqUZYb0hnfs3TM3hw=="],
|
|
20
|
+
|
|
21
|
+
"@csstools/color-helpers": ["@csstools/color-helpers@5.0.1", "", {}, "sha512-MKtmkA0BX87PKaO1NFRTFH+UnkgnmySQOvNxJubsadusqPEC2aJ9MOQiMceZJJ6oitUl/i0L6u0M1IrmAOmgBA=="],
|
|
22
|
+
|
|
23
|
+
"@csstools/css-calc": ["@csstools/css-calc@2.1.1", "", { "peerDependencies": { "@csstools/css-parser-algorithms": "^3.0.4", "@csstools/css-tokenizer": "^3.0.3" } }, "sha512-rL7kaUnTkL9K+Cvo2pnCieqNpTKgQzy5f+N+5Iuko9HAoasP+xgprVh7KN/MaJVvVL1l0EzQq2MoqBHKSrDrag=="],
|
|
24
|
+
|
|
25
|
+
"@csstools/css-color-parser": ["@csstools/css-color-parser@3.0.7", "", { "dependencies": { "@csstools/color-helpers": "^5.0.1", "@csstools/css-calc": "^2.1.1" }, "peerDependencies": { "@csstools/css-parser-algorithms": "^3.0.4", "@csstools/css-tokenizer": "^3.0.3" } }, "sha512-nkMp2mTICw32uE5NN+EsJ4f5N+IGFeCFu4bGpiKgb2Pq/7J/MpyLBeQ5ry4KKtRFZaYs6sTmcMYrSRIyj5DFKA=="],
|
|
26
|
+
|
|
27
|
+
"@csstools/css-parser-algorithms": ["@csstools/css-parser-algorithms@3.0.4", "", { "peerDependencies": { "@csstools/css-tokenizer": "^3.0.3" } }, "sha512-Up7rBoV77rv29d3uKHUIVubz1BTcgyUK72IvCQAbfbMv584xHcGKCKbWh7i8hPrRJ7qU4Y8IO3IY9m+iTB7P3A=="],
|
|
28
|
+
|
|
29
|
+
"@csstools/css-tokenizer": ["@csstools/css-tokenizer@3.0.3", "", {}, "sha512-UJnjoFsmxfKUdNYdWgOB0mWUypuLvAfQPH1+pyvRJs6euowbFkFC6P13w1l8mJyi3vxYMxc9kld5jZEGRQs6bw=="],
|
|
30
|
+
|
|
31
|
+
"@types/bun": ["@types/bun@1.2.4", "", { "dependencies": { "bun-types": "1.2.4" } }, "sha512-QtuV5OMR8/rdKJs213iwXDpfVvnskPXY/S0ZiFbsTjQZycuqPbMW8Gf/XhLfwE5njW8sxI2WjISURXPlHypMFA=="],
|
|
32
|
+
|
|
33
|
+
"@types/deno": ["@types/deno@2.0.0", "", {}, "sha512-O9/jRVlq93kqfkl4sYR5N7+Pz4ukzXVIbMnE/VgvpauNHsvjQ9iBVnJ3X0gAvMa2khcoFD8DSO7mQVCuiuDMPg=="],
|
|
34
|
+
|
|
35
|
+
"@types/jsdom": ["@types/jsdom@21.1.7", "", { "dependencies": { "@types/node": "*", "@types/tough-cookie": "*", "parse5": "^7.0.0" } }, "sha512-yOriVnggzrnQ3a9OKOCxaVuSug3w3/SbOj5i7VwXWZEyUNl3bLF9V3MfxGbZKuwqJOQyRfqXyROBB1CoZLFWzA=="],
|
|
36
|
+
|
|
37
|
+
"@types/node": ["@types/node@20.17.17", "", { "dependencies": { "undici-types": "~6.19.2" } }, "sha512-/WndGO4kIfMicEQLTi/mDANUu/iVUhT7KboZPdEqqHQ4aTS+3qT3U5gIqWDFV+XouorjfgGqvKILJeHhuQgFYg=="],
|
|
38
|
+
|
|
39
|
+
"@types/tough-cookie": ["@types/tough-cookie@4.0.5", "", {}, "sha512-/Ad8+nIOV7Rl++6f1BdKxFSMgmoqEoYbHRpPcx3JEfv8VRsQe9Z4mCXeJBzxs7mbHY/XOZZuXlRNfhpVPbs6ZA=="],
|
|
40
|
+
|
|
41
|
+
"@types/ws": ["@types/ws@8.5.14", "", { "dependencies": { "@types/node": "*" } }, "sha512-bd/YFLW+URhBzMXurx7lWByOu+xzU9+kb3RboOteXYDfW+tr+JZa99OyNmPINEGB/ahzKrEuc8rcv4gnpJmxTw=="],
|
|
42
|
+
|
|
43
|
+
"agent-base": ["agent-base@7.1.3", "", {}, "sha512-jRR5wdylq8CkOe6hei19GGZnxM6rBGwFl3Bg0YItGDimvjGtAvdZk4Pu6Cl4u4Igsws4a1fd1Vq3ezrhn4KmFw=="],
|
|
44
|
+
|
|
45
|
+
"asynckit": ["asynckit@0.4.0", "", {}, "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q=="],
|
|
46
|
+
|
|
47
|
+
"bun-types": ["bun-types@1.2.4", "", { "dependencies": { "@types/node": "*", "@types/ws": "~8.5.10" } }, "sha512-nDPymR207ZZEoWD4AavvEaa/KZe/qlrbMSchqpQwovPZCKc7pwMoENjEtHgMKaAjJhy+x6vfqSBA1QU3bJgs0Q=="],
|
|
48
|
+
|
|
49
|
+
"combined-stream": ["combined-stream@1.0.8", "", { "dependencies": { "delayed-stream": "~1.0.0" } }, "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg=="],
|
|
50
|
+
|
|
51
|
+
"cssstyle": ["cssstyle@4.2.1", "", { "dependencies": { "@asamuzakjp/css-color": "^2.8.2", "rrweb-cssom": "^0.8.0" } }, "sha512-9+vem03dMXG7gDmZ62uqmRiMRNtinIZ9ZyuF6BdxzfOD+FdN5hretzynkn0ReS2DO2GSw76RWHs0UmJPI2zUjw=="],
|
|
52
|
+
|
|
53
|
+
"data-urls": ["data-urls@5.0.0", "", { "dependencies": { "whatwg-mimetype": "^4.0.0", "whatwg-url": "^14.0.0" } }, "sha512-ZYP5VBHshaDAiVZxjbRVcFJpc+4xGgT0bK3vzy1HLN8jTO975HEbuYzZJcHoQEY5K1a0z8YayJkyVETa08eNTg=="],
|
|
54
|
+
|
|
55
|
+
"dayjs": ["dayjs@1.11.13", "", {}, "sha512-oaMBel6gjolK862uaPQOVTA7q3TZhuSvuMQAAglQDOWYO9A91IrAOUJEyKVlqJlHE0vq5p5UXxzdPfMH/x6xNg=="],
|
|
56
|
+
|
|
57
|
+
"debug": ["debug@4.4.0", "", { "dependencies": { "ms": "^2.1.3" } }, "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA=="],
|
|
58
|
+
|
|
59
|
+
"decimal.js": ["decimal.js@10.5.0", "", {}, "sha512-8vDa8Qxvr/+d94hSh5P3IJwI5t8/c0KsMp+g8bNw9cY2icONa5aPfvKeieW1WlG0WQYwwhJ7mjui2xtiePQSXw=="],
|
|
60
|
+
|
|
61
|
+
"delayed-stream": ["delayed-stream@1.0.0", "", {}, "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ=="],
|
|
62
|
+
|
|
63
|
+
"entities": ["entities@4.5.0", "", {}, "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw=="],
|
|
64
|
+
|
|
65
|
+
"form-data": ["form-data@4.0.1", "", { "dependencies": { "asynckit": "^0.4.0", "combined-stream": "^1.0.8", "mime-types": "^2.1.12" } }, "sha512-tzN8e4TX8+kkxGPK8D5u0FNmjPUjw3lwC9lSLxxoB/+GtsJG91CO8bSWy73APlgAZzZbXEYZJuxjkHH2w+Ezhw=="],
|
|
66
|
+
|
|
67
|
+
"html-encoding-sniffer": ["html-encoding-sniffer@4.0.0", "", { "dependencies": { "whatwg-encoding": "^3.1.1" } }, "sha512-Y22oTqIU4uuPgEemfz7NDJz6OeKf12Lsu+QC+s3BVpda64lTiMYCyGwg5ki4vFxkMwQdeZDl2adZoqUgdFuTgQ=="],
|
|
68
|
+
|
|
69
|
+
"http-proxy-agent": ["http-proxy-agent@7.0.2", "", { "dependencies": { "agent-base": "^7.1.0", "debug": "^4.3.4" } }, "sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig=="],
|
|
70
|
+
|
|
71
|
+
"https-proxy-agent": ["https-proxy-agent@7.0.6", "", { "dependencies": { "agent-base": "^7.1.2", "debug": "4" } }, "sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw=="],
|
|
72
|
+
|
|
73
|
+
"iconv-lite": ["iconv-lite@0.6.3", "", { "dependencies": { "safer-buffer": ">= 2.1.2 < 3.0.0" } }, "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw=="],
|
|
74
|
+
|
|
75
|
+
"is-potential-custom-element-name": ["is-potential-custom-element-name@1.0.1", "", {}, "sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ=="],
|
|
76
|
+
|
|
77
|
+
"jsdom": ["jsdom@26.0.0", "", { "dependencies": { "cssstyle": "^4.2.1", "data-urls": "^5.0.0", "decimal.js": "^10.4.3", "form-data": "^4.0.1", "html-encoding-sniffer": "^4.0.0", "http-proxy-agent": "^7.0.2", "https-proxy-agent": "^7.0.6", "is-potential-custom-element-name": "^1.0.1", "nwsapi": "^2.2.16", "parse5": "^7.2.1", "rrweb-cssom": "^0.8.0", "saxes": "^6.0.0", "symbol-tree": "^3.2.4", "tough-cookie": "^5.0.0", "w3c-xmlserializer": "^5.0.0", "webidl-conversions": "^7.0.0", "whatwg-encoding": "^3.1.1", "whatwg-mimetype": "^4.0.0", "whatwg-url": "^14.1.0", "ws": "^8.18.0", "xml-name-validator": "^5.0.0" }, "peerDependencies": { "canvas": "^3.0.0" }, "optionalPeers": ["canvas"] }, "sha512-BZYDGVAIriBWTpIxYzrXjv3E/4u8+/pSG5bQdIYCbNCGOvsPkDQfTVLAIXAf9ETdCpduCVTkDe2NNZ8NIwUVzw=="],
|
|
78
|
+
|
|
79
|
+
"lru-cache": ["lru-cache@10.4.3", "", {}, "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ=="],
|
|
80
|
+
|
|
81
|
+
"mime-db": ["mime-db@1.52.0", "", {}, "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg=="],
|
|
82
|
+
|
|
83
|
+
"mime-types": ["mime-types@2.1.35", "", { "dependencies": { "mime-db": "1.52.0" } }, "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw=="],
|
|
84
|
+
|
|
85
|
+
"ms": ["ms@2.1.3", "", {}, "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="],
|
|
86
|
+
|
|
87
|
+
"nwsapi": ["nwsapi@2.2.16", "", {}, "sha512-F1I/bimDpj3ncaNDhfyMWuFqmQDBwDB0Fogc2qpL3BWvkQteFD/8BzWuIRl83rq0DXfm8SGt/HFhLXZyljTXcQ=="],
|
|
88
|
+
|
|
89
|
+
"parse5": ["parse5@7.2.1", "", { "dependencies": { "entities": "^4.5.0" } }, "sha512-BuBYQYlv1ckiPdQi/ohiivi9Sagc9JG+Ozs0r7b/0iK3sKmrb0b9FdWdBbOdx6hBCM/F9Ir82ofnBhtZOjCRPQ=="],
|
|
90
|
+
|
|
91
|
+
"punycode": ["punycode@2.3.1", "", {}, "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg=="],
|
|
92
|
+
|
|
93
|
+
"rrweb-cssom": ["rrweb-cssom@0.8.0", "", {}, "sha512-guoltQEx+9aMf2gDZ0s62EcV8lsXR+0w8915TC3ITdn2YueuNjdAYh/levpU9nFaoChh9RUS5ZdQMrKfVEN9tw=="],
|
|
94
|
+
|
|
95
|
+
"safer-buffer": ["safer-buffer@2.1.2", "", {}, "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="],
|
|
96
|
+
|
|
97
|
+
"saxes": ["saxes@6.0.0", "", { "dependencies": { "xmlchars": "^2.2.0" } }, "sha512-xAg7SOnEhrm5zI3puOOKyy1OMcMlIJZYNJY7xLBwSze0UjhPLnWfj2GF2EpT0jmzaJKIWKHLsaSSajf35bcYnA=="],
|
|
98
|
+
|
|
99
|
+
"symbol-tree": ["symbol-tree@3.2.4", "", {}, "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw=="],
|
|
100
|
+
|
|
101
|
+
"tldts": ["tldts@6.1.77", "", { "dependencies": { "tldts-core": "^6.1.77" }, "bin": { "tldts": "bin/cli.js" } }, "sha512-lBpoWgy+kYmuXWQ83+R7LlJCnsd9YW8DGpZSHhrMl4b8Ly/1vzOie3OdtmUJDkKxcgRGOehDu5btKkty+JEe+g=="],
|
|
102
|
+
|
|
103
|
+
"tldts-core": ["tldts-core@6.1.77", "", {}, "sha512-bCaqm24FPk8OgBkM0u/SrEWJgHnhBWYqeBo6yUmcZJDCHt/IfyWBb+14CXdGi4RInMv4v7eUAin15W0DoA+Ytg=="],
|
|
104
|
+
|
|
105
|
+
"tough-cookie": ["tough-cookie@5.1.1", "", { "dependencies": { "tldts": "^6.1.32" } }, "sha512-Ek7HndSVkp10hmHP9V4qZO1u+pn1RU5sI0Fw+jCU3lyvuMZcgqsNgc6CmJJZyByK4Vm/qotGRJlfgAX8q+4JiA=="],
|
|
106
|
+
|
|
107
|
+
"tr46": ["tr46@5.0.0", "", { "dependencies": { "punycode": "^2.3.1" } }, "sha512-tk2G5R2KRwBd+ZN0zaEXpmzdKyOYksXwywulIX95MBODjSzMIuQnQ3m8JxgbhnL1LeVo7lqQKsYa1O3Htl7K5g=="],
|
|
108
|
+
|
|
109
|
+
"undici-types": ["undici-types@6.19.8", "", {}, "sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw=="],
|
|
110
|
+
|
|
111
|
+
"w3c-xmlserializer": ["w3c-xmlserializer@5.0.0", "", { "dependencies": { "xml-name-validator": "^5.0.0" } }, "sha512-o8qghlI8NZHU1lLPrpi2+Uq7abh4GGPpYANlalzWxyWteJOCsr/P+oPBA49TOLu5FTZO4d3F9MnWJfiMo4BkmA=="],
|
|
112
|
+
|
|
113
|
+
"webidl-conversions": ["webidl-conversions@7.0.0", "", {}, "sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g=="],
|
|
114
|
+
|
|
115
|
+
"whatwg-encoding": ["whatwg-encoding@3.1.1", "", { "dependencies": { "iconv-lite": "0.6.3" } }, "sha512-6qN4hJdMwfYBtE3YBTTHhoeuUrDBPZmbQaxWAqSALV/MeEnR5z1xd8UKud2RAkFoPkmB+hli1TZSnyi84xz1vQ=="],
|
|
116
|
+
|
|
117
|
+
"whatwg-mimetype": ["whatwg-mimetype@4.0.0", "", {}, "sha512-QaKxh0eNIi2mE9p2vEdzfagOKHCcj1pJ56EEHGQOVxp8r9/iszLUUV7v89x9O1p/T+NlTM5W7jW6+cz4Fq1YVg=="],
|
|
118
|
+
|
|
119
|
+
"whatwg-url": ["whatwg-url@14.1.1", "", { "dependencies": { "tr46": "^5.0.0", "webidl-conversions": "^7.0.0" } }, "sha512-mDGf9diDad/giZ/Sm9Xi2YcyzaFpbdLpJPr+E9fSkyQ7KpQD4SdFcugkRQYzhmfI4KeV4Qpnn2sKPdo+kmsgRQ=="],
|
|
120
|
+
|
|
121
|
+
"ws": ["ws@8.18.0", "", { "peerDependencies": { "bufferutil": "^4.0.1", "utf-8-validate": ">=5.0.2" }, "optionalPeers": ["bufferutil", "utf-8-validate"] }, "sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw=="],
|
|
122
|
+
|
|
123
|
+
"xml-name-validator": ["xml-name-validator@5.0.0", "", {}, "sha512-EvGK8EJ3DhaHfbRlETOWAS5pO9MZITeauHKJyb8wyajUfQUenkIg2MvLDTZ4T/TgIcm3HU0TFBgWWboAZ30UHg=="],
|
|
124
|
+
|
|
125
|
+
"xmlchars": ["xmlchars@2.2.0", "", {}, "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw=="],
|
|
126
|
+
}
|
|
127
|
+
}
|
package/deno.lock
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": "3",
|
|
3
|
+
"redirects": {
|
|
4
|
+
"https://deno.land/x/sleep/mod.ts": "https://deno.land/x/sleep@v1.3.0/mod.ts"
|
|
5
|
+
},
|
|
6
|
+
"remote": {
|
|
7
|
+
"https://deno.land/x/sleep@v1.3.0/mod.ts": "e9955ecd3228a000e29d46726cd6ab14b65cf83904e9b365f3a8d64ec61c1af3",
|
|
8
|
+
"https://deno.land/x/sleep@v1.3.0/sleep.ts": "b6abaca093b094b0c2bba94f287b19a60946a8d15764d168f83fcf555f5bb59e"
|
|
9
|
+
},
|
|
10
|
+
"workspace": {
|
|
11
|
+
"packageJson": {
|
|
12
|
+
"dependencies": [
|
|
13
|
+
"npm:@types/bun@^1.1.14",
|
|
14
|
+
"npm:@types/deno@^2.0.0",
|
|
15
|
+
"npm:@types/node@^20.4.2"
|
|
16
|
+
]
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
}
|
package/go.mod
ADDED
package/lib/gson-2.3.jar
ADDED
|
Binary file
|
package/main.js
ADDED
|
File without changes
|
package/package.json
CHANGED
|
@@ -1,26 +1,23 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vyckr/tachyon",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"
|
|
5
|
-
|
|
6
|
-
"
|
|
7
|
-
|
|
8
|
-
"dependencies": {
|
|
9
|
-
"@vyckr/byos": "^0.1.0"
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"author": "Chidelma",
|
|
5
|
+
"repository": {
|
|
6
|
+
"type": "git",
|
|
7
|
+
"url": "git+https://github.com/Chidelma/Tachyon.git"
|
|
10
8
|
},
|
|
11
|
-
"
|
|
12
|
-
"
|
|
13
|
-
|
|
14
|
-
|
|
9
|
+
"devDependencies": {
|
|
10
|
+
"@types/bun": "^1.2.4",
|
|
11
|
+
"@types/deno": "^2.0.0",
|
|
12
|
+
"@types/jsdom": "^21.1.7",
|
|
13
|
+
"@types/node": "^20.4.2"
|
|
15
14
|
},
|
|
16
15
|
"bin": {
|
|
17
|
-
"tach": "./src/
|
|
16
|
+
"tach": "./src/serve.ts",
|
|
17
|
+
"yon": "./src/client/dist.ts"
|
|
18
18
|
},
|
|
19
|
-
"
|
|
20
|
-
|
|
21
|
-
"repository": {
|
|
22
|
-
"type": "git",
|
|
23
|
-
"url": "git+https://github.com/Chidelma/Tachyon.git"
|
|
19
|
+
"bugs": {
|
|
20
|
+
"url": "https://github.com/Chidelma/Tachyon/issues"
|
|
24
21
|
},
|
|
25
22
|
"keywords": [
|
|
26
23
|
"tachyon",
|
|
@@ -29,8 +26,10 @@
|
|
|
29
26
|
"typescript",
|
|
30
27
|
"bun"
|
|
31
28
|
],
|
|
32
|
-
"
|
|
33
|
-
"
|
|
34
|
-
|
|
29
|
+
"license": "MIT",
|
|
30
|
+
"type": "module",
|
|
31
|
+
"dependencies": {
|
|
32
|
+
"dayjs": "^1.11.13",
|
|
33
|
+
"jsdom": "^26.0.0"
|
|
35
34
|
}
|
|
36
35
|
}
|
package/routes/DELETE
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
#!/usr/bin/env dart
|
|
2
|
+
import 'dart:convert';
|
|
3
|
+
import 'dart:io';
|
|
4
|
+
|
|
5
|
+
void main() async {
|
|
6
|
+
|
|
7
|
+
print('Executing Dart...');
|
|
8
|
+
|
|
9
|
+
await for (final line in stdin.transform(utf8.decoder).transform(const LineSplitter())) {
|
|
10
|
+
|
|
11
|
+
var ctx = jsonDecode(line);
|
|
12
|
+
|
|
13
|
+
ctx["message"] = "Hello from Dart!";
|
|
14
|
+
|
|
15
|
+
await File('/tmp/$pid').writeAsString(jsonEncode(ctx));
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
|
package/routes/GET
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
#!/usr/bin/env bun
|
|
2
|
+
for await(const chunk of Bun.stdin.stream()) {
|
|
3
|
+
|
|
4
|
+
console.log("Executing Bun....");
|
|
5
|
+
|
|
6
|
+
const data = new TextDecoder().decode(chunk)
|
|
7
|
+
|
|
8
|
+
const ctx = JSON.parse(data)
|
|
9
|
+
|
|
10
|
+
ctx.message = "Hello from Bun!"
|
|
11
|
+
|
|
12
|
+
const response = JSON.stringify(ctx)
|
|
13
|
+
|
|
14
|
+
await Bun.write(`/tmp/${process.pid}`, response)
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export {}
|
package/routes/HTML
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
<script>
|
|
2
|
+
const { default: dayjs } = await import('/modules/dayjs.js')
|
|
3
|
+
|
|
4
|
+
console.log(dayjs().format())
|
|
5
|
+
document.title = "Home"
|
|
6
|
+
|
|
7
|
+
console.log("Hello from JavaScript")
|
|
8
|
+
|
|
9
|
+
let greeting = "Hello from HTML!"
|
|
10
|
+
|
|
11
|
+
const arr = [1, 2, 3, 4, 5, 6, 7, 8, 9]
|
|
12
|
+
|
|
13
|
+
const start = 5
|
|
14
|
+
</script>
|
|
15
|
+
|
|
16
|
+
<h1>${greeting}</h1>
|
|
17
|
+
<input type="text" placeholder="Write Something" :value="greeting" @input="(value) => greeting = value" />
|
|
18
|
+
<br/>
|
|
19
|
+
<ty-counter :count="start" />
|
|
20
|
+
<ty-loop :for="const num of arr">
|
|
21
|
+
<ty-logic :if="num % 5 === 0">
|
|
22
|
+
<p>Half way there! Number ${num}</p>
|
|
23
|
+
</ty-logic>
|
|
24
|
+
<ty-logic :else>
|
|
25
|
+
<p>Number ${num}</p>
|
|
26
|
+
</ty-logic>
|
|
27
|
+
</ty-loop>
|
|
28
|
+
<ty-counter :count="start" />
|
package/routes/POST
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
#!/usr/bin/env -S java --source 22 --class-path /Users/iyor/Library/CloudStorage/Dropbox/myProjects/TACHYON/lib/gson-2.3.jar
|
|
2
|
+
|
|
3
|
+
import java.io.*;
|
|
4
|
+
import com.google.gson.JsonParser;
|
|
5
|
+
|
|
6
|
+
public class POST {
|
|
7
|
+
public static void main(String[] args) {
|
|
8
|
+
|
|
9
|
+
System.out.println("Executing Java...");
|
|
10
|
+
|
|
11
|
+
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
|
|
12
|
+
|
|
13
|
+
try {
|
|
14
|
+
|
|
15
|
+
var ctx = new JsonParser().parse(br.readLine()).getAsJsonObject();
|
|
16
|
+
|
|
17
|
+
ctx.addProperty("message", "Hello from Java!");
|
|
18
|
+
|
|
19
|
+
long pid = ProcessHandle.current().pid();
|
|
20
|
+
|
|
21
|
+
try (FileWriter file = new FileWriter("/tmp/" + pid)) {
|
|
22
|
+
file.write(ctx.toString());
|
|
23
|
+
file.flush();
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
} catch (IOException e) {
|
|
27
|
+
System.err.println("Error writing to file: " + e.getMessage());
|
|
28
|
+
} catch (Exception e) {
|
|
29
|
+
System.err.println("Error processing JSON: " + e.getMessage());
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
}
|
package/routes/SOCKET
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
#!/usr/bin/env -S deno run --allow-env --allow-write
|
|
2
|
+
import { pid } from 'node:process';
|
|
3
|
+
import { sleep } from "https://deno.land/x/sleep/mod.ts"
|
|
4
|
+
|
|
5
|
+
console.log("Executing Deno Socket....");
|
|
6
|
+
|
|
7
|
+
const ctx = JSON.parse("{}")
|
|
8
|
+
|
|
9
|
+
ctx.message = "Hello from Deno!"
|
|
10
|
+
|
|
11
|
+
const response = JSON.stringify(ctx)
|
|
12
|
+
|
|
13
|
+
const max = 2
|
|
14
|
+
|
|
15
|
+
let start = 0
|
|
16
|
+
|
|
17
|
+
while(start < max) {
|
|
18
|
+
|
|
19
|
+
await Deno.writeTextFile(`/tmp/${pid}`, response)
|
|
20
|
+
|
|
21
|
+
await sleep(0.1)
|
|
22
|
+
|
|
23
|
+
start++
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export {}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
#!/usr/bin/env rust-script
|
|
2
|
+
//! ```cargo
|
|
3
|
+
//! [dependencies]
|
|
4
|
+
//! serde_json = "1.0.135"
|
|
5
|
+
//! ```
|
|
6
|
+
use serde_json::{Value};
|
|
7
|
+
use std::process;
|
|
8
|
+
use std::collections::HashMap;
|
|
9
|
+
use std::fs;
|
|
10
|
+
use std::io::{self, BufRead};
|
|
11
|
+
|
|
12
|
+
fn main() {
|
|
13
|
+
|
|
14
|
+
println!("Executing Rust....");
|
|
15
|
+
|
|
16
|
+
let stdin = io::stdin();
|
|
17
|
+
|
|
18
|
+
for line in stdin.lock().lines() {
|
|
19
|
+
|
|
20
|
+
let mut ctx: HashMap<String, Value> = serde_json::from_str(&line.unwrap()).unwrap();
|
|
21
|
+
|
|
22
|
+
ctx.insert("message".to_string(), "Hello from Rust!".into());
|
|
23
|
+
|
|
24
|
+
// Output the JSON result
|
|
25
|
+
let data = serde_json::to_string(&ctx).expect("Failed to serialize JSON");
|
|
26
|
+
|
|
27
|
+
fs::write("/tmp/".to_owned() + &process::id().to_string(), data).expect("Unable to write file");
|
|
28
|
+
}
|
|
29
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
#!/usr/bin/perl
|
|
2
|
+
use strict;
|
|
3
|
+
use warnings;
|
|
4
|
+
use JSON;
|
|
5
|
+
use Data::Dumper;
|
|
6
|
+
|
|
7
|
+
print "Executing Perl...\n";
|
|
8
|
+
|
|
9
|
+
# Create JSON decoder object
|
|
10
|
+
my $json = JSON->new;
|
|
11
|
+
|
|
12
|
+
# Decode the JSON argument
|
|
13
|
+
my $ctx = $json->decode(<STDIN>);
|
|
14
|
+
|
|
15
|
+
$ctx->{message} = "Hello from Perl!";
|
|
16
|
+
|
|
17
|
+
# Open file for writing
|
|
18
|
+
open(my $file, '>', "/tmp/$$") or die "Cannot open file: $!";
|
|
19
|
+
|
|
20
|
+
# Write JSON encoded response to file
|
|
21
|
+
print $file $json->encode($ctx);
|
|
22
|
+
|
|
23
|
+
# Close file
|
|
24
|
+
close($file);
|