@live-change/server 0.1.20 → 0.1.21

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/lib/Renderer.js CHANGED
@@ -3,6 +3,8 @@ const path = require('path')
3
3
  const serialize = require('serialize-javascript')
4
4
  const renderTemplate = require('./renderTemplate.js')
5
5
 
6
+ const { SitemapStream } = require('sitemap')
7
+
6
8
  class Renderer {
7
9
  constructor(manifest, settings) {
8
10
  this.manifest = manifest
@@ -15,7 +17,9 @@ class Renderer {
15
17
  await this.setupVite()
16
18
  } else {
17
19
  const serverEntryPath = path.resolve(this.root, './dist/server/entry-server.js')
18
- this.renderer = require(serverEntryPath).render
20
+ this.module = require(serverEntryPath)
21
+ this.renderer = this.module.render
22
+ this.sitemap = this.module.sitemap
19
23
  const templatePath = path.resolve(this.root, 'dist/client/index.html')
20
24
  this.template = await fs.promises.readFile(templatePath, { encoding: 'utf-8' })
21
25
  }
@@ -117,6 +121,39 @@ class Renderer {
117
121
  }
118
122
  }
119
123
 
124
+ async getSitemap() {
125
+ if(this.settings.dev) {
126
+ /// Reload every request
127
+ const entryPath = path.resolve(this.root, 'src/entry-server.js')
128
+ return (await this.vite.ssrLoadModule(entryPath)).sitemap
129
+ } else {
130
+ return this.sitemap
131
+ }
132
+ }
133
+
134
+ async renderSitemap({ dao }, res) {
135
+ try {
136
+ res.header('Content-Type', 'application/xml')
137
+ res.status(200)
138
+ const smStream = new SitemapStream({ hostname: (process.env.BASE_HREF || "https://sitemap.com")+'/' })
139
+ smStream.pipe(res)
140
+ const sitemapFunction = await this.getSitemap()
141
+ const { sitemap, router } = await sitemapFunction({ dao })
142
+ function route(location, opts) {
143
+ smStream.write({ url: router.resolve(location).href, changefreq: 'daily', priority: 0.5, ...opts })
144
+ }
145
+ console.log("SR", sitemap, router)
146
+ await sitemap(route)
147
+ //route({ name: 'index' })
148
+ smStream.end()
149
+ } catch(err) {
150
+ console.error("SITEMAP RENDERING ERROR", err)
151
+ res.status(503)
152
+ res.end(`<h4>Internal server error</h4><pre>${err.stack || err.code || err}</pre>`)
153
+ //if(profileOp) await profileLog.end({ ...profileOp, state: 'error', error: err })
154
+ }
155
+ }
156
+
120
157
  fixStackTrace(e) {
121
158
  this.vite && this.vite.ssrFixStacktrace(e)
122
159
  }
package/lib/SsrServer.js CHANGED
@@ -54,6 +54,23 @@ class SsrServer {
54
54
  await this.setupSsr()
55
55
  }
56
56
 
57
+ async createDao(credentials, clientIp) {
58
+ let dao
59
+ if(this.settings.daoFactory) {
60
+ dao = await this.settings.daoFactory(credentials, clientIp)
61
+ } else {
62
+ const host = (this.settings.apiHost == '0.0.0.0' || !this.settings.apiHost)
63
+ ? 'localhost' : this.settings.apiHost
64
+ dao = await serverDao(credentials, clientIp, {
65
+ remoteUrl: `ws://${host}:${this.settings.apiPort || 8002}/api/ws`
66
+ })
67
+ }
68
+ if(!dao) {
69
+ throw new Error("Impossible to render page without data access object. Define apiServer or daoFactory!")
70
+ }
71
+ return dao
72
+ }
73
+
57
74
  async setupSsr() {
58
75
  const readCredentials = this.settings.readCredentials || ((req) => {
59
76
  const cookies = cookie.parse(req.headers.cookie || '')
@@ -70,6 +87,13 @@ class SsrServer {
70
87
  })
71
88
  }
72
89
  })
90
+
91
+ this.express.get('/sitemap.xml', async (req, res) => {
92
+ const sitemap = await this.renderer.getSitemap()
93
+ const clientIp = getIp(req)
94
+ const dao = await this.createDao({ sessionKey: 'sitemap' })
95
+ this.renderer.renderSitemap({ dao, clientIp }, res)
96
+ })
73
97
  this.express.use('*', async (req, res) => {
74
98
  const url = req.originalUrl
75
99
  const clientIp = getIp(req)
@@ -77,19 +101,7 @@ class SsrServer {
77
101
  const credentials = readCredentials(req)
78
102
  const windowId = this.uidGenerator()
79
103
  try {
80
- let dao
81
- if(this.settings.daoFactory) {
82
- dao = await this.settings.daoFactory(credentials, clientIp)
83
- } else {
84
- const host = (this.settings.apiHost == '0.0.0.0' || !this.settings.apiHost)
85
- ? 'localhost' : this.settings.apiHost
86
- dao = await serverDao(credentials, clientIp, {
87
- remoteUrl: `ws://${host}:${this.settings.apiPort || 8002}/api/ws`
88
- })
89
- }
90
- if(!dao)
91
- throw new Error("Impossible to render page without data access object. Define apiServer or daoFactory!")
92
-
104
+ const dao = await this.createDao(credentials, clientIp)
93
105
  const version = this.version
94
106
 
95
107
  let html
@@ -39,6 +39,19 @@ async function setupApiServer(settings) {
39
39
  }
40
40
  })
41
41
  }
42
+ if(settings.dbAccess) {
43
+ local.serverDatabase = {
44
+ observable(what) {
45
+ return app.dao.observable(['database', ...what.slice(1)])
46
+ },
47
+ get(what) {
48
+ return app.dao.get(['database', ...what.slice(1)])
49
+ },
50
+ request(what, ...args) {
51
+ return app.dao.request(['database', ...what.slice(1)], ...args)
52
+ }
53
+ }
54
+ }
42
55
  return local
43
56
  },
44
57
  shareDefinition: true,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@live-change/server",
3
- "version": "0.1.20",
3
+ "version": "0.1.21",
4
4
  "description": "Live Change Framework - server",
5
5
  "main": "index.js",
6
6
  "scripts": {
@@ -36,6 +36,7 @@
36
36
  "@live-change/sockjs": "^0.4.0-rc.1",
37
37
  "websocket": "^1.0.34",
38
38
  "yargs": "^17.3.0",
39
- "express-static-gzip": "2.1.1"
39
+ "express-static-gzip": "2.1.1",
40
+ "sitemap": "^6.3.6"
40
41
  }
41
42
  }