@vindo/react 0.0.1

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/README.md ADDED
@@ -0,0 +1,12 @@
1
+ ## Cross-origin (CORS)
2
+ Resource sharing restriction for Web and API
3
+
4
+
5
+ ## Installation
6
+ ```
7
+ npm install @vindo/cors
8
+ ```
9
+ Or
10
+ ```
11
+ yarn add @vindo/cors
12
+ ```
package/client.js ADDED
@@ -0,0 +1,95 @@
1
+ /*
2
+ * @vindo/react
3
+ * Copyright(c) 2025 Ruel Mindo
4
+ * MIT Licensed
5
+ */
6
+
7
+ 'use strict'
8
+
9
+
10
+ const React = require('node_modules/react')
11
+
12
+
13
+
14
+ /**
15
+ * Http Request
16
+ */
17
+ function request({path, data}, opts = {}) {
18
+ if(data && typeof data !== 'object') {
19
+ throw TypeError(`Invalid type of 'data'. Expected value of type 'object' but got ${typeof data}'.`)
20
+ }
21
+
22
+ var uuid = window.crypto.randomUUID()
23
+ var opts = {
24
+ ...opts,
25
+ headers: {
26
+ ...opts.headers,
27
+ 'X-Fetch-Request-Token': uuid
28
+ }
29
+ }
30
+
31
+ var url = new URL(location.href)
32
+ if(path) {
33
+ url = new URL(path, location.origin)
34
+ }
35
+
36
+ if(opts.method == 'GET') {
37
+ if(data) {
38
+ for(var i in data) {
39
+ url.searchParams.append(i, data[i])
40
+ }
41
+ }
42
+ }
43
+
44
+ return fetch(url, opts).then((res) => {
45
+ return res.headers.get('X-Fetch-Response') == uuid && res.json()
46
+ })
47
+ }
48
+
49
+
50
+
51
+ /**
52
+ * Http Request
53
+ */
54
+ exports.http = {
55
+ get(args = {}) {
56
+ return request(args, {...args.headers, method: 'GET'})
57
+ },
58
+ post(args = {}) {
59
+ return request(args, {
60
+ body: JSON.stringify(args.data ?? {}),
61
+ method: 'POST',
62
+ headers: {
63
+ ...args.headers,
64
+ 'Content-Type': 'application/json'
65
+ }
66
+ })
67
+ }
68
+ }
69
+
70
+
71
+ /**
72
+ * HTML Holder
73
+ */
74
+ exports.View = function View({children}) {
75
+ return children
76
+ }
77
+
78
+ /**
79
+ * Find current route
80
+ */
81
+ exports.HydrateContent = function HydrateContent({data, meta, ...props}) {
82
+
83
+ if(data && React.isValidElement(data.content)) {
84
+ return React.createElement('main', props, data.content)
85
+ }
86
+
87
+ return React.createElement('main', props, React.Children.map(props.children, (child) => {
88
+ if(!data || !child.props.name) {
89
+ return
90
+ }
91
+ if(meta.name == child.props.name) {
92
+ return child.props.component(data.content)
93
+ }
94
+ }))
95
+ }
package/index.d.ts ADDED
@@ -0,0 +1,14 @@
1
+ declare module '@vindo/react' {
2
+ export const HTTPResponse: {
3
+ get(cb:Function): void
4
+ post(cb:Function): void
5
+ }
6
+ export function server(): Function;
7
+ }
8
+
9
+ declare module '@vindo/react/client' {
10
+ export const http:any;
11
+ export function View(props): any;
12
+ export function Hydrate(props): any;
13
+ export function HydrateContent(props): any;
14
+ }
package/index.js ADDED
@@ -0,0 +1,224 @@
1
+ /*
2
+ * @vindo/react
3
+ * Copyright(c) 2025 Ruel Mindo
4
+ * MIT Licensed
5
+ */
6
+
7
+ 'use strict'
8
+
9
+
10
+ const path = require('node:path')
11
+ const React = require('node_modules/react')
12
+ const ReactDom = require('node_modules/react-dom/server')
13
+
14
+ /**
15
+ * Shorthand
16
+ */
17
+ const map = React.Children.map
18
+ const clone = React.cloneElement
19
+ const create = React.createElement
20
+ const isValid = React.isValidElement
21
+
22
+
23
+ var data = {}
24
+ var index = require(path.resolve('src/react'))
25
+ if(index.default) {
26
+ index = index.default
27
+ }
28
+
29
+
30
+ /**
31
+ * Set data
32
+ * @param {object} el
33
+ * @param {object} meta
34
+ */
35
+ function set(el, meta) {
36
+ const {children: content, ...props} = el.props
37
+
38
+ /**
39
+ * Use id if no name provided
40
+ */
41
+ var name = props.name ?? props.id
42
+ var opt = {
43
+ name,
44
+ meta: {name, ...meta}
45
+ }
46
+
47
+ switch(el.type.name) {
48
+ case 'View':
49
+ Object.assign(opt, {bundle: true, content: content ?? props})
50
+ break
51
+ default:
52
+ Object.assign(opt, {bundle: false, content: el})
53
+ }
54
+
55
+
56
+ function children(item) {
57
+ var children = item.props.children
58
+
59
+ if(item.type == 'head') {
60
+ children = head(children, opt)
61
+ }
62
+ if(item.type == 'body') {
63
+ children = body(children, opt)
64
+ }
65
+ return clone(item, item.props, children)
66
+ }
67
+
68
+
69
+ const app = index({name, content: opt.content, ...meta})
70
+ return {
71
+ name,
72
+ html: html(
73
+ clone(app, {}, map(app.props.children, children))
74
+ )
75
+ }
76
+ }
77
+
78
+
79
+ /**
80
+ * Set data to first level of children function
81
+ * @param {array} children
82
+ * @param {object} data
83
+ */
84
+ function inherit(children, data) {
85
+
86
+ return children.map((child, key) => {
87
+ if(typeof child.type == 'function') {
88
+ child = child.type({...child.props, data, meta: data.meta})
89
+ }
90
+ return clone(child, {key})
91
+ })
92
+ }
93
+
94
+
95
+ /**
96
+ * Set DOCTYPE
97
+ * @param {object} html
98
+ */
99
+ function html(obj) {
100
+ return '<!DOCTYPE html>'.concat(ReactDom.renderToString(obj))
101
+ }
102
+
103
+
104
+ /**
105
+ * Add a bundle script to head
106
+ * @param children
107
+ * @param args
108
+ */
109
+ function head(children, args) {
110
+ const env = process.env
111
+
112
+ if(!args.bundle) {
113
+ return children
114
+ }
115
+
116
+ const queries = new URLSearchParams({
117
+ hash: env.UUID,
118
+ name: args.name,
119
+ port: (env.NODE_ENV == 'dev' || env.NODE_ENV == 'develop' || env.NODE_ENV == 'development') && env.DEV_SERVER_PORT
120
+ })
121
+
122
+ return children.concat(
123
+ create('script', {
124
+ key: 0,
125
+ id: 'bundle',
126
+ type: 'module',
127
+ src: '/bundle.js?'.concat(queries.toString())
128
+ })
129
+ )
130
+ }
131
+
132
+
133
+ /**
134
+ * Set meta data to children
135
+ * @param {array} children
136
+ * @param {object} args
137
+ */
138
+ function body(children, args) {
139
+
140
+ if(typeof children.type == 'function') {
141
+ const type = children.type(args)
142
+
143
+ if(!type) {
144
+ return
145
+ }
146
+ if(type.props.children) {
147
+ children = type.props.children
148
+ }
149
+ }
150
+ data[args.name] = inherit(children, args)
151
+
152
+ return data[args.name]
153
+ }
154
+
155
+
156
+ /**
157
+ * Client fetch response
158
+ *
159
+ * @param {object} req
160
+ * @param {object} res
161
+ */
162
+ function HTTPResponse(req, res) {
163
+ const token = req.get('x-fetch-request-token')
164
+
165
+ const response = function(data) {
166
+ if(token) {
167
+ res.json(data, 200, {'X-Fetch-Response': token})
168
+ }
169
+ }
170
+
171
+ return {
172
+ get(cb) {
173
+ if(req.method == 'GET')
174
+ response(cb(req.query))
175
+ },
176
+ post(cb) {
177
+ if(req.method == 'POST')
178
+ response(cb(req.body))
179
+ }
180
+ }
181
+ }
182
+
183
+
184
+ /**
185
+ * Middleware
186
+ */
187
+ exports.server = function server() {
188
+
189
+ return function(req, res, next, {env, meta, events, exception}) {
190
+ exports.HTTPResponse = HTTPResponse(req, res)
191
+ /**
192
+ * JSX object
193
+ */
194
+ if(req.is(env.UUID)) {
195
+ data = res.json(data[req.query.name]) ?? {}
196
+ return
197
+ }
198
+
199
+ events.on('render', function(component) {
200
+ if(req.get('x-fetch-request-token')) {
201
+ return
202
+ }
203
+
204
+ if(isValid(component)) {
205
+ var data = set(component, meta)
206
+ if(!data) {
207
+ return
208
+ }
209
+ /**
210
+ * Return nothing if the request not matched with the component.
211
+ */
212
+ const errors = Object.keys(exception.statuses).concat('error')
213
+ if(data.name && req.name) {
214
+ if(req.route.back && data.name !== req.name && !errors.includes(data.name)) {
215
+ return
216
+ }
217
+ }
218
+ return data
219
+ }
220
+ })
221
+
222
+ next()
223
+ }
224
+ }
package/package.json ADDED
@@ -0,0 +1,23 @@
1
+ {
2
+ "name": "@vindo/react",
3
+ "version": "0.0.1",
4
+ "description": "React SSR",
5
+ "main": "./index.js",
6
+ "types": "./index.d.ts",
7
+ "publishConfig": {
8
+ "access": "public"
9
+ },
10
+ "scripts": {},
11
+ "repository": {
12
+ "type": "git",
13
+ "url": "git+https://github.com/rmindo/vindo.git",
14
+ "directory": "packages/react"
15
+ },
16
+ "homepage": "https://github.com/rmindo/vindo/tree/main/packages/react#readme",
17
+ "keywords": [
18
+ "react"
19
+ ],
20
+ "author": "Ruel Mindo",
21
+ "license": "MIT",
22
+ "dependencies": {}
23
+ }