@kensio/yulin 1.6.1 → 1.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (208) hide show
  1. package/README.md +72 -0
  2. package/dist/cli/sim-cli.d.ts +20 -0
  3. package/dist/cli/sim-cli.d.ts.map +1 -0
  4. package/dist/cli/sim-cli.js +42 -0
  5. package/dist/cli/sim-cli.js.map +1 -0
  6. package/dist/cli/watch/sim-watch-arguments.d.ts +30 -0
  7. package/dist/cli/watch/sim-watch-arguments.d.ts.map +1 -0
  8. package/dist/cli/watch/sim-watch-arguments.js +67 -0
  9. package/dist/cli/watch/sim-watch-arguments.js.map +1 -0
  10. package/dist/cli/watch/sim-watch-child-environment.d.ts +30 -0
  11. package/dist/cli/watch/sim-watch-child-environment.d.ts.map +1 -0
  12. package/dist/cli/watch/sim-watch-child-environment.js +51 -0
  13. package/dist/cli/watch/sim-watch-child-environment.js.map +1 -0
  14. package/dist/cli/watch/sim-watch-child-message.d.ts +19 -0
  15. package/dist/cli/watch/sim-watch-child-message.d.ts.map +1 -0
  16. package/dist/cli/watch/sim-watch-child-message.js +42 -0
  17. package/dist/cli/watch/sim-watch-child-message.js.map +1 -0
  18. package/dist/cli/watch/sim-watch-child-process.d.ts +22 -0
  19. package/dist/cli/watch/sim-watch-child-process.d.ts.map +1 -0
  20. package/dist/cli/watch/sim-watch-child-process.js +33 -0
  21. package/dist/cli/watch/sim-watch-child-process.js.map +1 -0
  22. package/dist/cli/watch/sim-watch-child-shutdown.d.ts +28 -0
  23. package/dist/cli/watch/sim-watch-child-shutdown.d.ts.map +1 -0
  24. package/dist/cli/watch/sim-watch-child-shutdown.js +59 -0
  25. package/dist/cli/watch/sim-watch-child-shutdown.js.map +1 -0
  26. package/dist/cli/watch/sim-watch-child.d.ts +42 -0
  27. package/dist/cli/watch/sim-watch-child.d.ts.map +1 -0
  28. package/dist/cli/watch/sim-watch-child.js +62 -0
  29. package/dist/cli/watch/sim-watch-child.js.map +1 -0
  30. package/dist/cli/watch/sim-watch-command.d.ts +22 -0
  31. package/dist/cli/watch/sim-watch-command.d.ts.map +1 -0
  32. package/dist/cli/watch/sim-watch-command.js +41 -0
  33. package/dist/cli/watch/sim-watch-command.js.map +1 -0
  34. package/dist/cli/watch/sim-watch-event-path.d.ts +27 -0
  35. package/dist/cli/watch/sim-watch-event-path.d.ts.map +1 -0
  36. package/dist/cli/watch/sim-watch-event-path.js +48 -0
  37. package/dist/cli/watch/sim-watch-event-path.js.map +1 -0
  38. package/dist/cli/watch/sim-watch-ignore.d.ts +15 -0
  39. package/dist/cli/watch/sim-watch-ignore.d.ts.map +1 -0
  40. package/dist/cli/watch/sim-watch-ignore.js +64 -0
  41. package/dist/cli/watch/sim-watch-ignore.js.map +1 -0
  42. package/dist/cli/watch/sim-watch-loop-guard.d.ts +35 -0
  43. package/dist/cli/watch/sim-watch-loop-guard.d.ts.map +1 -0
  44. package/dist/cli/watch/sim-watch-loop-guard.js +51 -0
  45. package/dist/cli/watch/sim-watch-loop-guard.js.map +1 -0
  46. package/dist/cli/watch/sim-watch-reporter.d.ts +38 -0
  47. package/dist/cli/watch/sim-watch-reporter.d.ts.map +1 -0
  48. package/dist/cli/watch/sim-watch-reporter.js +65 -0
  49. package/dist/cli/watch/sim-watch-reporter.js.map +1 -0
  50. package/dist/cli/watch/sim-watch-restarts.d.ts +30 -0
  51. package/dist/cli/watch/sim-watch-restarts.d.ts.map +1 -0
  52. package/dist/cli/watch/sim-watch-restarts.js +62 -0
  53. package/dist/cli/watch/sim-watch-restarts.js.map +1 -0
  54. package/dist/cli/watch/sim-watch-supervisor.d.ts +52 -0
  55. package/dist/cli/watch/sim-watch-supervisor.d.ts.map +1 -0
  56. package/dist/cli/watch/sim-watch-supervisor.js +127 -0
  57. package/dist/cli/watch/sim-watch-supervisor.js.map +1 -0
  58. package/dist/cli/watch/sim-watch-watcher.d.ts +69 -0
  59. package/dist/cli/watch/sim-watch-watcher.d.ts.map +1 -0
  60. package/dist/cli/watch/sim-watch-watcher.js +144 -0
  61. package/dist/cli/watch/sim-watch-watcher.js.map +1 -0
  62. package/dist/cli/yulin.d.ts +3 -0
  63. package/dist/cli/yulin.d.ts.map +1 -0
  64. package/dist/cli/yulin.js +14 -0
  65. package/dist/cli/yulin.js.map +1 -0
  66. package/dist/serve/http/live-reload/sim-live-reload-client.d.ts +32 -0
  67. package/dist/serve/http/live-reload/sim-live-reload-client.d.ts.map +1 -0
  68. package/dist/serve/http/live-reload/sim-live-reload-client.js +55 -0
  69. package/dist/serve/http/live-reload/sim-live-reload-client.js.map +1 -0
  70. package/dist/serve/http/live-reload/sim-live-reload-injectable.d.ts +47 -0
  71. package/dist/serve/http/live-reload/sim-live-reload-injectable.d.ts.map +1 -0
  72. package/dist/serve/http/live-reload/sim-live-reload-injectable.js +86 -0
  73. package/dist/serve/http/live-reload/sim-live-reload-injectable.js.map +1 -0
  74. package/dist/serve/http/live-reload/sim-live-reload-injector.d.ts +22 -0
  75. package/dist/serve/http/live-reload/sim-live-reload-injector.d.ts.map +1 -0
  76. package/dist/serve/http/live-reload/sim-live-reload-injector.js +72 -0
  77. package/dist/serve/http/live-reload/sim-live-reload-injector.js.map +1 -0
  78. package/dist/serve/http/live-reload/sim-live-reload-report.d.ts +18 -0
  79. package/dist/serve/http/live-reload/sim-live-reload-report.d.ts.map +1 -0
  80. package/dist/serve/http/live-reload/sim-live-reload-report.js +27 -0
  81. package/dist/serve/http/live-reload/sim-live-reload-report.js.map +1 -0
  82. package/dist/serve/http/live-reload/sim-live-reload-script.d.ts +20 -0
  83. package/dist/serve/http/live-reload/sim-live-reload-script.d.ts.map +1 -0
  84. package/dist/serve/http/live-reload/sim-live-reload-script.js +45 -0
  85. package/dist/serve/http/live-reload/sim-live-reload-script.js.map +1 -0
  86. package/dist/serve/http/live-reload/sim-live-reload.config.d.ts +12 -0
  87. package/dist/serve/http/live-reload/sim-live-reload.config.d.ts.map +1 -0
  88. package/dist/serve/http/live-reload/sim-live-reload.config.js +19 -0
  89. package/dist/serve/http/live-reload/sim-live-reload.config.js.map +1 -0
  90. package/dist/serve/http/live-reload/sim-live-reload.d.ts +52 -0
  91. package/dist/serve/http/live-reload/sim-live-reload.d.ts.map +1 -0
  92. package/dist/serve/http/live-reload/sim-live-reload.js +82 -0
  93. package/dist/serve/http/live-reload/sim-live-reload.js.map +1 -0
  94. package/dist/serve/http/live-reload/sim-local-live-reload.d.ts +42 -0
  95. package/dist/serve/http/live-reload/sim-local-live-reload.d.ts.map +1 -0
  96. package/dist/serve/http/live-reload/sim-local-live-reload.js +60 -0
  97. package/dist/serve/http/live-reload/sim-local-live-reload.js.map +1 -0
  98. package/dist/serve/http/local-server/node-server-port-binder.d.ts +39 -0
  99. package/dist/serve/http/local-server/node-server-port-binder.d.ts.map +1 -0
  100. package/dist/serve/http/local-server/node-server-port-binder.js +71 -0
  101. package/dist/serve/http/local-server/node-server-port-binder.js.map +1 -0
  102. package/dist/serve/http/local-server/node-server-port.d.ts +10 -0
  103. package/dist/serve/http/local-server/node-server-port.d.ts.map +1 -0
  104. package/dist/serve/http/local-server/node-server-port.js +19 -0
  105. package/dist/serve/http/local-server/node-server-port.js.map +1 -0
  106. package/dist/serve/http/local-server/sim-aws-local-port.error.d.ts +13 -0
  107. package/dist/serve/http/local-server/sim-aws-local-port.error.d.ts.map +1 -0
  108. package/dist/serve/http/local-server/sim-aws-local-port.error.js +16 -0
  109. package/dist/serve/http/local-server/sim-aws-local-port.error.js.map +1 -0
  110. package/dist/serve/http/local-server/sim-aws-local-request-handler.d.ts +14 -1
  111. package/dist/serve/http/local-server/sim-aws-local-request-handler.d.ts.map +1 -1
  112. package/dist/serve/http/local-server/sim-aws-local-request-handler.js +20 -2
  113. package/dist/serve/http/local-server/sim-aws-local-request-handler.js.map +1 -1
  114. package/dist/serve/http/local-server/sim-aws-local-server.d.ts +23 -0
  115. package/dist/serve/http/local-server/sim-aws-local-server.d.ts.map +1 -1
  116. package/dist/serve/http/local-server/sim-aws-local-server.js +41 -16
  117. package/dist/serve/http/local-server/sim-aws-local-server.js.map +1 -1
  118. package/dist/serve/http/local-server/sim-aws-local.config.d.ts +2 -0
  119. package/dist/serve/http/local-server/sim-aws-local.config.d.ts.map +1 -1
  120. package/dist/serve/http/local-server/sim-aws-local.config.js +6 -0
  121. package/dist/serve/http/local-server/sim-aws-local.config.js.map +1 -1
  122. package/dist/serve/index.d.ts +3 -0
  123. package/dist/serve/index.d.ts.map +1 -1
  124. package/dist/serve/index.js +3 -0
  125. package/dist/serve/index.js.map +1 -1
  126. package/dist/service/cloudformation/authorize/sim-cloudformation-authorization.d.ts +44 -0
  127. package/dist/service/cloudformation/authorize/sim-cloudformation-authorization.d.ts.map +1 -0
  128. package/dist/service/cloudformation/authorize/sim-cloudformation-authorization.js +53 -0
  129. package/dist/service/cloudformation/authorize/sim-cloudformation-authorization.js.map +1 -0
  130. package/dist/service/cloudformation/command/update-stack/update-stack.handler.d.ts +7 -0
  131. package/dist/service/cloudformation/command/update-stack/update-stack.handler.d.ts.map +1 -1
  132. package/dist/service/cloudformation/command/update-stack/update-stack.handler.js +3 -1
  133. package/dist/service/cloudformation/command/update-stack/update-stack.handler.js.map +1 -1
  134. package/dist/service/cloudformation/deploy/sim-cfn-template-deployer.d.ts +19 -0
  135. package/dist/service/cloudformation/deploy/sim-cfn-template-deployer.d.ts.map +1 -1
  136. package/dist/service/cloudformation/deploy/sim-cfn-template-deployer.js +40 -1
  137. package/dist/service/cloudformation/deploy/sim-cfn-template-deployer.js.map +1 -1
  138. package/dist/service/cloudformation/deploy/sim-cfn-template-file-deployment.d.ts +10 -0
  139. package/dist/service/cloudformation/deploy/sim-cfn-template-file-deployment.d.ts.map +1 -0
  140. package/dist/service/cloudformation/deploy/sim-cfn-template-file-deployment.js +14 -0
  141. package/dist/service/cloudformation/deploy/sim-cfn-template-file-deployment.js.map +1 -0
  142. package/dist/service/cloudformation/deploy/sim-cfn-template-file-loader.d.ts +11 -0
  143. package/dist/service/cloudformation/deploy/sim-cfn-template-file-loader.d.ts.map +1 -1
  144. package/dist/service/cloudformation/deploy/sim-cfn-template-file-loader.js +5 -0
  145. package/dist/service/cloudformation/deploy/sim-cfn-template-file-loader.js.map +1 -1
  146. package/dist/service/cloudformation/deploy/sim-cfn-template-file-updater.d.ts +49 -0
  147. package/dist/service/cloudformation/deploy/sim-cfn-template-file-updater.d.ts.map +1 -0
  148. package/dist/service/cloudformation/deploy/sim-cfn-template-file-updater.js +59 -0
  149. package/dist/service/cloudformation/deploy/sim-cfn-template-file-updater.js.map +1 -0
  150. package/dist/service/cloudformation/index.d.ts +1 -0
  151. package/dist/service/cloudformation/index.d.ts.map +1 -1
  152. package/dist/service/cloudformation/sim-cloudformation.d.ts +30 -5
  153. package/dist/service/cloudformation/sim-cloudformation.d.ts.map +1 -1
  154. package/dist/service/cloudformation/sim-cloudformation.js +45 -14
  155. package/dist/service/cloudformation/sim-cloudformation.js.map +1 -1
  156. package/dist/service/cloudformation/stack/sim-cfn-stack-resource-operations.d.ts +10 -1
  157. package/dist/service/cloudformation/stack/sim-cfn-stack-resource-operations.d.ts.map +1 -1
  158. package/dist/service/cloudformation/stack/sim-cfn-stack-resource-operations.js +12 -1
  159. package/dist/service/cloudformation/stack/sim-cfn-stack-resource-operations.js.map +1 -1
  160. package/dist/service/cloudformation/stack/sim-cfn-stack.d.ts +14 -1
  161. package/dist/service/cloudformation/stack/sim-cfn-stack.d.ts.map +1 -1
  162. package/dist/service/cloudformation/stack/sim-cfn-stack.js +10 -1
  163. package/dist/service/cloudformation/stack/sim-cfn-stack.js.map +1 -1
  164. package/dist/service/cloudformation/stack/update/sim-cfn-stack-updater.d.ts +8 -0
  165. package/dist/service/cloudformation/stack/update/sim-cfn-stack-updater.d.ts.map +1 -1
  166. package/dist/service/cloudformation/stack/update/sim-cfn-stack-updater.js +9 -1
  167. package/dist/service/cloudformation/stack/update/sim-cfn-stack-updater.js.map +1 -1
  168. package/dist/service/cloudformation/watch/sim-cfn-template-file-events.d.ts +30 -0
  169. package/dist/service/cloudformation/watch/sim-cfn-template-file-events.d.ts.map +1 -0
  170. package/dist/service/cloudformation/watch/sim-cfn-template-file-events.js +51 -0
  171. package/dist/service/cloudformation/watch/sim-cfn-template-file-events.js.map +1 -0
  172. package/dist/service/cloudformation/watch/sim-cfn-template-file-watch.d.ts +39 -0
  173. package/dist/service/cloudformation/watch/sim-cfn-template-file-watch.d.ts.map +1 -0
  174. package/dist/service/cloudformation/watch/sim-cfn-template-file-watch.js +73 -0
  175. package/dist/service/cloudformation/watch/sim-cfn-template-file-watch.js.map +1 -0
  176. package/dist/service/cloudformation/watch/sim-cfn-template-file-watches.d.ts +46 -0
  177. package/dist/service/cloudformation/watch/sim-cfn-template-file-watches.d.ts.map +1 -0
  178. package/dist/service/cloudformation/watch/sim-cfn-template-file-watches.js +0 -0
  179. package/dist/service/cloudformation/watch/sim-cfn-template-file-watches.js.map +1 -0
  180. package/dist/service/cloudformation/watch/sim-cfn-template-watch-report.d.ts +25 -0
  181. package/dist/service/cloudformation/watch/sim-cfn-template-watch-report.d.ts.map +1 -0
  182. package/dist/service/cloudformation/watch/sim-cfn-template-watch-report.js +35 -0
  183. package/dist/service/cloudformation/watch/sim-cfn-template-watch-report.js.map +1 -0
  184. package/dist/service/cloudformation/watch/sim-cfn-template-watch-update.d.ts +44 -0
  185. package/dist/service/cloudformation/watch/sim-cfn-template-watch-update.d.ts.map +1 -0
  186. package/dist/service/cloudformation/watch/sim-cfn-template-watch-update.js +75 -0
  187. package/dist/service/cloudformation/watch/sim-cfn-template-watch-update.js.map +1 -0
  188. package/dist/service/cloudformation/watch/sim-cfn-template-watch.type.d.ts +30 -0
  189. package/dist/service/cloudformation/watch/sim-cfn-template-watch.type.d.ts.map +1 -0
  190. package/dist/service/cloudformation/watch/sim-cfn-template-watch.type.js +2 -0
  191. package/dist/service/cloudformation/watch/sim-cfn-template-watch.type.js.map +1 -0
  192. package/dist/service/s3/bucket/sim-s3-bucket-access.d.ts +4 -0
  193. package/dist/service/s3/bucket/sim-s3-bucket-access.d.ts.map +1 -1
  194. package/dist/service/s3/bucket/sim-s3-bucket-access.js +6 -0
  195. package/dist/service/s3/bucket/sim-s3-bucket-access.js.map +1 -1
  196. package/dist/watch/sim-watch-runtime.d.ts +76 -0
  197. package/dist/watch/sim-watch-runtime.d.ts.map +1 -0
  198. package/dist/watch/sim-watch-runtime.js +124 -0
  199. package/dist/watch/sim-watch-runtime.js.map +1 -0
  200. package/dist/watch/sim-watch-settle.d.ts +32 -0
  201. package/dist/watch/sim-watch-settle.d.ts.map +1 -0
  202. package/dist/watch/sim-watch-settle.js +43 -0
  203. package/dist/watch/sim-watch-settle.js.map +1 -0
  204. package/dist/watch/sim-watch.config.d.ts +22 -0
  205. package/dist/watch/sim-watch.config.d.ts.map +1 -0
  206. package/dist/watch/sim-watch.config.js +39 -0
  207. package/dist/watch/sim-watch.config.js.map +1 -0
  208. package/package.json +4 -1
@@ -0,0 +1,86 @@
1
+ const sigV4AuthorizationPrefix = "AWS4-HMAC-SHA256";
2
+ const htmlContentType = "text/html";
3
+ const awsNamePrefix = "x-amz-";
4
+ /**
5
+ * Whether any of these header or query parameter names is an AWS one.
6
+ */
7
+ function hasAwsPrefixed(names) {
8
+ for (const name of names) {
9
+ if (name.toLowerCase().startsWith(awsNamePrefix)) {
10
+ return true;
11
+ }
12
+ }
13
+ return false;
14
+ }
15
+ /**
16
+ * Decides whether a response can carry the live reload script.
17
+ *
18
+ * The simulator's own account of a request goes in headers and never in the
19
+ * body, so that a response keeps the shape the real service returns. Injecting
20
+ * a script breaks that rule, and these checks are what keep the breakage to the
21
+ * one case it is worth it for: an HTML page a browser is about to render.
22
+ *
23
+ * Everything else comes back untouched. An SDK reading an HTML Object out of a
24
+ * Bucket has to get the bytes that were stored, and a range or an encoded body
25
+ * cannot take an insertion at all.
26
+ */
27
+ export class SimLiveReloadInjectable {
28
+ /**
29
+ * Whether the script belongs in this response.
30
+ */
31
+ allows(request, response) {
32
+ return (this.hasBody(request, response) &&
33
+ this.isWholeResponse(response) &&
34
+ this.isPlainHtml(response) &&
35
+ this.isBrowserRequest(request) &&
36
+ !this.isSignedRequest(request) &&
37
+ !this.isSdkRequest(request));
38
+ }
39
+ hasBody(request, response) {
40
+ return request.method !== "HEAD" && response.body !== null;
41
+ }
42
+ /**
43
+ * A partial response is a slice of a body, and a slice cannot take an
44
+ * insertion without the offsets the client already asked for going wrong.
45
+ */
46
+ isWholeResponse(response) {
47
+ return response.status !== 206;
48
+ }
49
+ /**
50
+ * The media type has to be `text/html` itself, not merely start with it, so a
51
+ * type such as `text/htmlx` is left alone. An encoded body would have to be
52
+ * decoded, changed and re-encoded, and the simulator has no reason to be in
53
+ * that business.
54
+ */
55
+ isPlainHtml(response) {
56
+ const contentType = response.headers.get("content-type") ?? "";
57
+ const [mediaType = ""] = contentType.split(";");
58
+ return (mediaType.trim().toLowerCase() === htmlContentType &&
59
+ !response.headers.has("content-encoding"));
60
+ }
61
+ /**
62
+ * Something asking for HTML is something that will render it.
63
+ */
64
+ isBrowserRequest(request) {
65
+ const accept = request.headers.get("accept") ?? "";
66
+ return accept.toLowerCase().includes(htmlContentType);
67
+ }
68
+ /**
69
+ * A signature comes either in a header or, for a presigned URL, in the query
70
+ * string. A presigned URL is the one signed request a browser makes with an
71
+ * ordinary HTML `accept` header, which is what an address bar sends, so
72
+ * missing it would mean handing back an Object with bytes added to it.
73
+ */
74
+ isSignedRequest(request) {
75
+ const authorization = request.headers.get("authorization") ?? "";
76
+ return (authorization.startsWith(sigV4AuthorizationPrefix) ||
77
+ hasAwsPrefixed(new URL(request.url).searchParams.keys()));
78
+ }
79
+ /**
80
+ * An `x-amz-*` header is an AWS client talking, whether it signed or not.
81
+ */
82
+ isSdkRequest(request) {
83
+ return hasAwsPrefixed(request.headers.keys());
84
+ }
85
+ }
86
+ //# sourceMappingURL=sim-live-reload-injectable.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sim-live-reload-injectable.js","sourceRoot":"","sources":["../../../../src/serve/http/live-reload/sim-live-reload-injectable.ts"],"names":[],"mappings":"AAAA,MAAM,wBAAwB,GAAG,kBAAkB,CAAC;AACpD,MAAM,eAAe,GAAG,WAAW,CAAC;AACpC,MAAM,aAAa,GAAG,QAAQ,CAAC;AAE/B;;GAEG;AACH,SAAS,cAAc,CAAC,KAA+B;IACrD,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,IAAI,IAAI,CAAC,WAAW,EAAE,CAAC,UAAU,CAAC,aAAa,CAAC,EAAE,CAAC;YACjD,OAAO,IAAI,CAAC;QACd,CAAC;IACH,CAAC;IAED,OAAO,KAAK,CAAC;AACf,CAAC;AAED;;;;;;;;;;;GAWG;AACH,MAAM,OAAO,uBAAuB;IAClC;;OAEG;IACH,MAAM,CAAC,OAAgB,EAAE,QAAkB;QACzC,OAAO,CACL,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,QAAQ,CAAC;YAC/B,IAAI,CAAC,eAAe,CAAC,QAAQ,CAAC;YAC9B,IAAI,CAAC,WAAW,CAAC,QAAQ,CAAC;YAC1B,IAAI,CAAC,gBAAgB,CAAC,OAAO,CAAC;YAC9B,CAAC,IAAI,CAAC,eAAe,CAAC,OAAO,CAAC;YAC9B,CAAC,IAAI,CAAC,YAAY,CAAC,OAAO,CAAC,CAC5B,CAAC;IACJ,CAAC;IAEO,OAAO,CAAC,OAAgB,EAAE,QAAkB;QAClD,OAAO,OAAO,CAAC,MAAM,KAAK,MAAM,IAAI,QAAQ,CAAC,IAAI,KAAK,IAAI,CAAC;IAC7D,CAAC;IAED;;;OAGG;IACK,eAAe,CAAC,QAAkB;QACxC,OAAO,QAAQ,CAAC,MAAM,KAAK,GAAG,CAAC;IACjC,CAAC;IAED;;;;;OAKG;IACK,WAAW,CAAC,QAAkB;QACpC,MAAM,WAAW,GAAG,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC,IAAI,EAAE,CAAC;QAC/D,MAAM,CAAC,SAAS,GAAG,EAAE,CAAC,GAAG,WAAW,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QAEhD,OAAO,CACL,SAAS,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,KAAK,eAAe;YAClD,CAAC,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,kBAAkB,CAAC,CAC1C,CAAC;IACJ,CAAC;IAED;;OAEG;IACK,gBAAgB,CAAC,OAAgB;QACvC,MAAM,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC;QAEnD,OAAO,MAAM,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,eAAe,CAAC,CAAC;IACxD,CAAC;IAED;;;;;OAKG;IACK,eAAe,CAAC,OAAgB;QACtC,MAAM,aAAa,GAAG,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,eAAe,CAAC,IAAI,EAAE,CAAC;QAEjE,OAAO,CACL,aAAa,CAAC,UAAU,CAAC,wBAAwB,CAAC;YAClD,cAAc,CAAC,IAAI,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,YAAY,CAAC,IAAI,EAAE,CAAC,CACzD,CAAC;IACJ,CAAC;IAED;;OAEG;IACK,YAAY,CAAC,OAAgB;QACnC,OAAO,cAAc,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC;IAChD,CAAC;CACF"}
@@ -0,0 +1,22 @@
1
+ /**
2
+ * Puts the live reload script into HTML on its way to a browser.
3
+ *
4
+ * The script goes in at the end of the document, so the page has parsed before
5
+ * a connection is opened. The bytes of the body change, so anything describing
6
+ * those bytes has to change with them: `content-length` is recomputed, and
7
+ * `etag` and `last-modified` are dropped rather than left describing the
8
+ * stored Object the page no longer is.
9
+ *
10
+ * An injected page is also not stored. A cached copy would outlive the reload
11
+ * it was injected for, and a page held in the browser cache is a page live
12
+ * reload cannot reach.
13
+ */
14
+ export declare class SimLiveReloadInjector {
15
+ private readonly injectable;
16
+ /**
17
+ * Return the response a browser should get, injected if it can take it.
18
+ */
19
+ injectInto(request: Request, response: Response): Promise<Response>;
20
+ private inject;
21
+ }
22
+ //# sourceMappingURL=sim-live-reload-injector.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sim-live-reload-injector.d.ts","sourceRoot":"","sources":["../../../../src/serve/http/live-reload/sim-live-reload-injector.ts"],"names":[],"mappings":"AAIA;;;;;;;;;;;;GAYG;AACH,qBAAa,qBAAqB;IAChC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAiC;IAE5D;;OAEG;IACG,UAAU,CAAC,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,QAAQ,GAAG,OAAO,CAAC,QAAQ,CAAC,CAMxE;YAEa,MAAM;CAgBrB"}
@@ -0,0 +1,72 @@
1
+ import { SimLiveReloadInjectable } from "./sim-live-reload-injectable.js";
2
+ import { simLiveReloadScriptTag } from "./sim-live-reload-script.js";
3
+ import { simLiveReloadHeaderName } from "./sim-live-reload.config.js";
4
+ /**
5
+ * Puts the live reload script into HTML on its way to a browser.
6
+ *
7
+ * The script goes in at the end of the document, so the page has parsed before
8
+ * a connection is opened. The bytes of the body change, so anything describing
9
+ * those bytes has to change with them: `content-length` is recomputed, and
10
+ * `etag` and `last-modified` are dropped rather than left describing the
11
+ * stored Object the page no longer is.
12
+ *
13
+ * An injected page is also not stored. A cached copy would outlive the reload
14
+ * it was injected for, and a page held in the browser cache is a page live
15
+ * reload cannot reach.
16
+ */
17
+ export class SimLiveReloadInjector {
18
+ injectable = new SimLiveReloadInjectable();
19
+ /**
20
+ * Return the response a browser should get, injected if it can take it.
21
+ */
22
+ async injectInto(request, response) {
23
+ if (!this.injectable.allows(request, response)) {
24
+ return response;
25
+ }
26
+ return this.inject(response);
27
+ }
28
+ async inject(response) {
29
+ const body = insertScriptTag(await response.text());
30
+ const headers = new Headers(response.headers);
31
+ headers.delete("etag");
32
+ headers.delete("last-modified");
33
+ headers.set("content-length", String(Buffer.byteLength(body)));
34
+ headers.set("cache-control", "no-store");
35
+ headers.set(simLiveReloadHeaderName, "injected");
36
+ return new Response(body, {
37
+ status: response.status,
38
+ statusText: response.statusText,
39
+ headers,
40
+ });
41
+ }
42
+ }
43
+ // Matched against the document as written, rather than against a lowercased
44
+ // copy, because lowercasing can change a string's length and move every offset
45
+ // after the character that changed.
46
+ const closingTagPatterns = [/<\/body\s*>/gi, /<\/html\s*>/gi];
47
+ /**
48
+ * Put the script at the end of the document, wherever that turns out to be.
49
+ *
50
+ * A closing tag is the ordinary case. HTML without one is still something a
51
+ * browser will render, so appending is better than declining to reload it.
52
+ */
53
+ function insertScriptTag(html) {
54
+ for (const pattern of closingTagPatterns) {
55
+ const at = lastMatchIndex(html, pattern);
56
+ if (at !== -1) {
57
+ return html.slice(0, at) + simLiveReloadScriptTag + html.slice(at);
58
+ }
59
+ }
60
+ return html + simLiveReloadScriptTag;
61
+ }
62
+ /**
63
+ * Where the document's own closing tag is, rather than one inside it.
64
+ */
65
+ function lastMatchIndex(html, pattern) {
66
+ let index = -1;
67
+ for (const match of html.matchAll(pattern)) {
68
+ index = match.index;
69
+ }
70
+ return index;
71
+ }
72
+ //# sourceMappingURL=sim-live-reload-injector.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sim-live-reload-injector.js","sourceRoot":"","sources":["../../../../src/serve/http/live-reload/sim-live-reload-injector.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,uBAAuB,EAAE,MAAM,iCAAiC,CAAC;AAC1E,OAAO,EAAE,sBAAsB,EAAE,MAAM,6BAA6B,CAAC;AACrE,OAAO,EAAE,uBAAuB,EAAE,MAAM,6BAA6B,CAAC;AAEtE;;;;;;;;;;;;GAYG;AACH,MAAM,OAAO,qBAAqB;IACf,UAAU,GAAG,IAAI,uBAAuB,EAAE,CAAC;IAE5D;;OAEG;IACH,KAAK,CAAC,UAAU,CAAC,OAAgB,EAAE,QAAkB;QACnD,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,OAAO,EAAE,QAAQ,CAAC,EAAE,CAAC;YAC/C,OAAO,QAAQ,CAAC;QAClB,CAAC;QAED,OAAO,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;IAC/B,CAAC;IAEO,KAAK,CAAC,MAAM,CAAC,QAAkB;QACrC,MAAM,IAAI,GAAG,eAAe,CAAC,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC,CAAC;QACpD,MAAM,OAAO,GAAG,IAAI,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;QAE9C,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;QACvB,OAAO,CAAC,MAAM,CAAC,eAAe,CAAC,CAAC;QAChC,OAAO,CAAC,GAAG,CAAC,gBAAgB,EAAE,MAAM,CAAC,MAAM,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAC/D,OAAO,CAAC,GAAG,CAAC,eAAe,EAAE,UAAU,CAAC,CAAC;QACzC,OAAO,CAAC,GAAG,CAAC,uBAAuB,EAAE,UAAU,CAAC,CAAC;QAEjD,OAAO,IAAI,QAAQ,CAAC,IAAI,EAAE;YACxB,MAAM,EAAE,QAAQ,CAAC,MAAM;YACvB,UAAU,EAAE,QAAQ,CAAC,UAAU;YAC/B,OAAO;SACR,CAAC,CAAC;IACL,CAAC;CACF;AAED,4EAA4E;AAC5E,+EAA+E;AAC/E,oCAAoC;AACpC,MAAM,kBAAkB,GAAG,CAAC,eAAe,EAAE,eAAe,CAAC,CAAC;AAE9D;;;;;GAKG;AACH,SAAS,eAAe,CAAC,IAAY;IACnC,KAAK,MAAM,OAAO,IAAI,kBAAkB,EAAE,CAAC;QACzC,MAAM,EAAE,GAAG,cAAc,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;QAEzC,IAAI,EAAE,KAAK,CAAC,CAAC,EAAE,CAAC;YACd,OAAO,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,sBAAsB,GAAG,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;QACrE,CAAC;IACH,CAAC;IAED,OAAO,IAAI,GAAG,sBAAsB,CAAC;AACvC,CAAC;AAED;;GAEG;AACH,SAAS,cAAc,CAAC,IAAY,EAAE,OAAe;IACnD,IAAI,KAAK,GAAG,CAAC,CAAC,CAAC;IAEf,KAAK,MAAM,KAAK,IAAI,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC;QAC3C,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC;IACtB,CAAC;IAED,OAAO,KAAK,CAAC;AACf,CAAC"}
@@ -0,0 +1,18 @@
1
+ /**
2
+ * Says on startup that live reload is on.
3
+ *
4
+ * Live reload is the one thing the simulator does that changes a response body,
5
+ * which is otherwise the shape the real service returns. Something a served
6
+ * page did not ask for is worth being told about, once, at the point it starts
7
+ * happening, rather than being found later in a page's source.
8
+ *
9
+ * It goes to the console because the simulator has no logger of its own, the
10
+ * same as every other warning it raises.
11
+ */
12
+ export declare class SimLiveReloadReport {
13
+ /**
14
+ * Report live reload on a server that has just started listening.
15
+ */
16
+ announce(port: string): void;
17
+ }
18
+ //# sourceMappingURL=sim-live-reload-report.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sim-live-reload-report.d.ts","sourceRoot":"","sources":["../../../../src/serve/http/live-reload/sim-live-reload-report.ts"],"names":[],"mappings":"AAGA;;;;;;;;;;GAUG;AACH,qBAAa,mBAAmB;IAC9B;;OAEG;IACH,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAU3B;CACF"}
@@ -0,0 +1,27 @@
1
+ import { simAwsLocalConfig } from "../local-server/sim-aws-local.config.js";
2
+ import { simLiveReloadConfig } from "./sim-live-reload.config.js";
3
+ /**
4
+ * Says on startup that live reload is on.
5
+ *
6
+ * Live reload is the one thing the simulator does that changes a response body,
7
+ * which is otherwise the shape the real service returns. Something a served
8
+ * page did not ask for is worth being told about, once, at the point it starts
9
+ * happening, rather than being found later in a page's source.
10
+ *
11
+ * It goes to the console because the simulator has no logger of its own, the
12
+ * same as every other warning it raises.
13
+ */
14
+ export class SimLiveReloadReport {
15
+ /**
16
+ * Report live reload on a server that has just started listening.
17
+ */
18
+ announce(port) {
19
+ const channel = `http://${simAwsLocalConfig.hostname}:${port}${simLiveReloadConfig.channelPath}`;
20
+ // eslint-disable-next-line no-console
21
+ console.warn(`Simulated AWS live reload is on. HTML responses to browser requests ` +
22
+ `carry a reload script, so those responses are not byte for byte what ` +
23
+ `the real service would return. The reload channel is served at ` +
24
+ `${channel} on every served hostname.`);
25
+ }
26
+ }
27
+ //# sourceMappingURL=sim-live-reload-report.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sim-live-reload-report.js","sourceRoot":"","sources":["../../../../src/serve/http/live-reload/sim-live-reload-report.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,yCAAyC,CAAC;AAC5E,OAAO,EAAE,mBAAmB,EAAE,MAAM,6BAA6B,CAAC;AAElE;;;;;;;;;;GAUG;AACH,MAAM,OAAO,mBAAmB;IAC9B;;OAEG;IACH,QAAQ,CAAC,IAAY;QACnB,MAAM,OAAO,GAAG,UAAU,iBAAiB,CAAC,QAAQ,IAAI,IAAI,GAAG,mBAAmB,CAAC,WAAW,EAAE,CAAC;QAEjG,sCAAsC;QACtC,OAAO,CAAC,IAAI,CACV,sEAAsE;YACpE,uEAAuE;YACvE,iEAAiE;YACjE,GAAG,OAAO,4BAA4B,CACzC,CAAC;IACJ,CAAC;CACF"}
@@ -0,0 +1,20 @@
1
+ /**
2
+ * The script a served page runs to reload itself.
3
+ *
4
+ * It reloads on two signals. An explicit `reload` event is a reload the
5
+ * simulator asked for. A `boot` event carrying an id other than the one this
6
+ * page first saw means it is talking to a process that has restarted, which is
7
+ * how a restart reaches a page without the outgoing and incoming processes
8
+ * having to agree on anything. Reconnecting to the same id, which is what a
9
+ * dropped connection to a still running process gives, does nothing.
10
+ *
11
+ * A `reloading` event says a reload is on its way. The page is left to decide
12
+ * what to make of that, through an attribute it can style, rather than having
13
+ * anything drawn over it.
14
+ */
15
+ export declare const simLiveReloadScript: string;
16
+ /**
17
+ * The script as it goes into a page.
18
+ */
19
+ export declare const simLiveReloadScriptTag: string;
20
+ //# sourceMappingURL=sim-live-reload-script.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sim-live-reload-script.d.ts","sourceRoot":"","sources":["../../../../src/serve/http/live-reload/sim-live-reload-script.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,mBAAmB,QAwB1B,CAAC;AAEP;;GAEG;AACH,eAAO,MAAM,sBAAsB,QAAqE,CAAC"}
@@ -0,0 +1,45 @@
1
+ import { simLiveReloadConfig } from "./sim-live-reload.config.js";
2
+ /**
3
+ * The script a served page runs to reload itself.
4
+ *
5
+ * It reloads on two signals. An explicit `reload` event is a reload the
6
+ * simulator asked for. A `boot` event carrying an id other than the one this
7
+ * page first saw means it is talking to a process that has restarted, which is
8
+ * how a restart reaches a page without the outgoing and incoming processes
9
+ * having to agree on anything. Reconnecting to the same id, which is what a
10
+ * dropped connection to a still running process gives, does nothing.
11
+ *
12
+ * A `reloading` event says a reload is on its way. The page is left to decide
13
+ * what to make of that, through an attribute it can style, rather than having
14
+ * anything drawn over it.
15
+ */
16
+ export const simLiveReloadScript = `(() => {
17
+ if (window.simAwsLiveReload) {
18
+ return;
19
+ }
20
+ window.simAwsLiveReload = true;
21
+
22
+ let bootId = null;
23
+ const source = new EventSource("${simLiveReloadConfig.channelPath}");
24
+
25
+ source.addEventListener("boot", (event) => {
26
+ if (bootId !== null && bootId !== event.data) {
27
+ window.location.reload();
28
+ return;
29
+ }
30
+ bootId = event.data;
31
+ });
32
+
33
+ source.addEventListener("reload", () => {
34
+ window.location.reload();
35
+ });
36
+
37
+ source.addEventListener("reloading", () => {
38
+ document.documentElement.dataset.simAwsLiveReload = "reloading";
39
+ });
40
+ })();`;
41
+ /**
42
+ * The script as it goes into a page.
43
+ */
44
+ export const simLiveReloadScriptTag = `<script data-sim-aws-live-reload>${simLiveReloadScript}</script>`;
45
+ //# sourceMappingURL=sim-live-reload-script.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sim-live-reload-script.js","sourceRoot":"","sources":["../../../../src/serve/http/live-reload/sim-live-reload-script.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,MAAM,6BAA6B,CAAC;AAElE;;;;;;;;;;;;;GAaG;AACH,MAAM,CAAC,MAAM,mBAAmB,GAAG;;;;;;;oCAOC,mBAAmB,CAAC,WAAW;;;;;;;;;;;;;;;;;MAiB7D,CAAC;AAEP;;GAEG;AACH,MAAM,CAAC,MAAM,sBAAsB,GAAG,oCAAoC,mBAAmB,WAAW,CAAC"}
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Configuration for the live reload channel served on localhost.
3
+ */
4
+ export declare const simLiveReloadConfig: {
5
+ channelPath: string;
6
+ clientRetryMs: number;
7
+ };
8
+ /**
9
+ * Reports that a response carries the injected live reload script.
10
+ */
11
+ export declare const simLiveReloadHeaderName = "x-sim-aws-live-reload";
12
+ //# sourceMappingURL=sim-live-reload.config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sim-live-reload.config.d.ts","sourceRoot":"","sources":["../../../../src/serve/http/live-reload/sim-live-reload.config.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,eAAO,MAAM,mBAAmB;IAK9B,WAAW;IAIX,aAAa;CACd,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,uBAAuB,0BAA0B,CAAC"}
@@ -0,0 +1,19 @@
1
+ /**
2
+ * Configuration for the live reload channel served on localhost.
3
+ */
4
+ export const simLiveReloadConfig = {
5
+ // Reserved on every served hostname, so the injected script can ask for it
6
+ // with a relative path whatever host the page was served from. The cost is
7
+ // that a simulated distribution cannot serve anything at this path while live
8
+ // reload is on.
9
+ channelPath: "/__sim-aws/live-reload",
10
+ // How soon a browser reconnects after the connection drops. The default is
11
+ // several seconds, which is the gap between a restarted process being ready
12
+ // and the page noticing.
13
+ clientRetryMs: 500,
14
+ };
15
+ /**
16
+ * Reports that a response carries the injected live reload script.
17
+ */
18
+ export const simLiveReloadHeaderName = "x-sim-aws-live-reload";
19
+ //# sourceMappingURL=sim-live-reload.config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sim-live-reload.config.js","sourceRoot":"","sources":["../../../../src/serve/http/live-reload/sim-live-reload.config.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,MAAM,CAAC,MAAM,mBAAmB,GAAG;IACjC,2EAA2E;IAC3E,2EAA2E;IAC3E,8EAA8E;IAC9E,gBAAgB;IAChB,WAAW,EAAE,wBAAwB;IACrC,2EAA2E;IAC3E,4EAA4E;IAC5E,yBAAyB;IACzB,aAAa,EAAE,GAAG;CACnB,CAAC;AAEF;;GAEG;AACH,MAAM,CAAC,MAAM,uBAAuB,GAAG,uBAAuB,CAAC"}
@@ -0,0 +1,52 @@
1
+ import type { IncomingMessage, ServerResponse } from "node:http";
2
+ interface SimLiveReloadProperties {
3
+ readonly bootId?: string;
4
+ }
5
+ /**
6
+ * Reloads a browser looking at a page the simulator served.
7
+ *
8
+ * Yulin is the only thing in the response path for a page served from a
9
+ * simulated distribution, Function URL or Bucket website, so it is the only
10
+ * thing that can tell the browser to reload. Pages get a script, the script
11
+ * holds a connection open, and this is the end that decides what to say on it.
12
+ *
13
+ * The boot id is what makes a restart work. It identifies this process to the
14
+ * pages connected to it, and a page that reconnects to a different one knows
15
+ * it is looking at output from a process that is no longer running.
16
+ */
17
+ export declare class SimLiveReload {
18
+ private readonly bootId;
19
+ private readonly clients;
20
+ private readonly injector;
21
+ constructor(properties?: SimLiveReloadProperties);
22
+ /**
23
+ * Whether this request is for the reload channel rather than for a simulated
24
+ * service. The path is reserved on every served hostname, so a page can ask
25
+ * for it relative to wherever it was served from.
26
+ */
27
+ isChannelRequest(request: IncomingMessage): boolean;
28
+ /**
29
+ * Open the reload channel for a browser, and tell it which process it has
30
+ * reached.
31
+ */
32
+ connect(response: ServerResponse): void;
33
+ /**
34
+ * Put the reload script into a response, if that response can take it.
35
+ */
36
+ injectInto(request: Request, response: Response): Promise<Response>;
37
+ /**
38
+ * Reload every connected browser now.
39
+ */
40
+ reload(): void;
41
+ /**
42
+ * Say a reload is coming, then let the connections go.
43
+ *
44
+ * The page learns that the gap it is about to see is a restart rather than a
45
+ * server that has died. Ending the connections rather than leaving them for
46
+ * the browser to notice is what makes the reconnection prompt.
47
+ */
48
+ stopping(): void;
49
+ private send;
50
+ }
51
+ export {};
52
+ //# sourceMappingURL=sim-live-reload.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sim-live-reload.d.ts","sourceRoot":"","sources":["../../../../src/serve/http/live-reload/sim-live-reload.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAKjE,UAAU,uBAAuB;IAC/B,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;CAC1B;AAED;;;;;;;;;;;GAWG;AACH,qBAAa,aAAa;IACxB,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAS;IAChC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAkC;IAC1D,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAA+B;IAExD,YAAY,UAAU,GAAE,uBAA4B,EAGnD;IAED;;;;OAIG;IACH,gBAAgB,CAAC,OAAO,EAAE,eAAe,GAAG,OAAO,CAWlD;IAED;;;OAGG;IACH,OAAO,CAAC,QAAQ,EAAE,cAAc,GAAG,IAAI,CAUtC;IAED;;OAEG;IACG,UAAU,CAAC,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,QAAQ,GAAG,OAAO,CAAC,QAAQ,CAAC,CAExE;IAED;;OAEG;IACH,MAAM,IAAI,IAAI,CAEb;IAED;;;;;;OAMG;IACH,QAAQ,IAAI,IAAI,CAQf;IAED,OAAO,CAAC,IAAI;CAKb"}
@@ -0,0 +1,82 @@
1
+ import { randomUUID } from "node:crypto";
2
+ import { SimLiveReloadClient } from "./sim-live-reload-client.js";
3
+ import { SimLiveReloadInjector } from "./sim-live-reload-injector.js";
4
+ import { simLiveReloadConfig } from "./sim-live-reload.config.js";
5
+ /**
6
+ * Reloads a browser looking at a page the simulator served.
7
+ *
8
+ * Yulin is the only thing in the response path for a page served from a
9
+ * simulated distribution, Function URL or Bucket website, so it is the only
10
+ * thing that can tell the browser to reload. Pages get a script, the script
11
+ * holds a connection open, and this is the end that decides what to say on it.
12
+ *
13
+ * The boot id is what makes a restart work. It identifies this process to the
14
+ * pages connected to it, and a page that reconnects to a different one knows
15
+ * it is looking at output from a process that is no longer running.
16
+ */
17
+ export class SimLiveReload {
18
+ bootId;
19
+ clients = new Set();
20
+ injector = new SimLiveReloadInjector();
21
+ constructor(properties = {}) {
22
+ const { bootId = randomUUID() } = properties;
23
+ this.bootId = bootId;
24
+ }
25
+ /**
26
+ * Whether this request is for the reload channel rather than for a simulated
27
+ * service. The path is reserved on every served hostname, so a page can ask
28
+ * for it relative to wherever it was served from.
29
+ */
30
+ isChannelRequest(request) {
31
+ if (request.method !== "GET") {
32
+ return false;
33
+ }
34
+ const path = new URL(request.url ?? "/", "http://sim-aws.invalid").pathname.replace(/\/$/, "");
35
+ return path === simLiveReloadConfig.channelPath;
36
+ }
37
+ /**
38
+ * Open the reload channel for a browser, and tell it which process it has
39
+ * reached.
40
+ */
41
+ connect(response) {
42
+ const client = new SimLiveReloadClient(response);
43
+ this.clients.add(client);
44
+ client.onClose(() => {
45
+ this.clients.delete(client);
46
+ });
47
+ client.open();
48
+ client.send("boot", this.bootId);
49
+ }
50
+ /**
51
+ * Put the reload script into a response, if that response can take it.
52
+ */
53
+ async injectInto(request, response) {
54
+ return this.injector.injectInto(request, response);
55
+ }
56
+ /**
57
+ * Reload every connected browser now.
58
+ */
59
+ reload() {
60
+ this.send("reload");
61
+ }
62
+ /**
63
+ * Say a reload is coming, then let the connections go.
64
+ *
65
+ * The page learns that the gap it is about to see is a restart rather than a
66
+ * server that has died. Ending the connections rather than leaving them for
67
+ * the browser to notice is what makes the reconnection prompt.
68
+ */
69
+ stopping() {
70
+ this.send("reloading");
71
+ for (const client of this.clients) {
72
+ client.end();
73
+ }
74
+ this.clients.clear();
75
+ }
76
+ send(event) {
77
+ for (const client of this.clients) {
78
+ client.send(event, this.bootId);
79
+ }
80
+ }
81
+ }
82
+ //# sourceMappingURL=sim-live-reload.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sim-live-reload.js","sourceRoot":"","sources":["../../../../src/serve/http/live-reload/sim-live-reload.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAEzC,OAAO,EAAE,mBAAmB,EAAE,MAAM,6BAA6B,CAAC;AAClE,OAAO,EAAE,qBAAqB,EAAE,MAAM,+BAA+B,CAAC;AACtE,OAAO,EAAE,mBAAmB,EAAE,MAAM,6BAA6B,CAAC;AAMlE;;;;;;;;;;;GAWG;AACH,MAAM,OAAO,aAAa;IACP,MAAM,CAAS;IACf,OAAO,GAAG,IAAI,GAAG,EAAuB,CAAC;IACzC,QAAQ,GAAG,IAAI,qBAAqB,EAAE,CAAC;IAExD,YAAY,UAAU,GAA4B,EAAE;QAClD,MAAM,EAAE,MAAM,GAAG,UAAU,EAAE,EAAE,GAAG,UAAU,CAAC;QAC7C,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;IACvB,CAAC;IAED;;;;OAIG;IACH,gBAAgB,CAAC,OAAwB;QACvC,IAAI,OAAO,CAAC,MAAM,KAAK,KAAK,EAAE,CAAC;YAC7B,OAAO,KAAK,CAAC;QACf,CAAC;QAED,MAAM,IAAI,GAAG,IAAI,GAAG,CAClB,OAAO,CAAC,GAAG,IAAI,GAAG,EAClB,wBAAwB,CACzB,CAAC,QAAQ,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;QAE9B,OAAO,IAAI,KAAK,mBAAmB,CAAC,WAAW,CAAC;IAClD,CAAC;IAED;;;OAGG;IACH,OAAO,CAAC,QAAwB;QAC9B,MAAM,MAAM,GAAG,IAAI,mBAAmB,CAAC,QAAQ,CAAC,CAAC;QAEjD,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;QACzB,MAAM,CAAC,OAAO,CAAC,GAAG,EAAE;YAClB,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;QAC9B,CAAC,CAAC,CAAC;QAEH,MAAM,CAAC,IAAI,EAAE,CAAC;QACd,MAAM,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC;IACnC,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,UAAU,CAAC,OAAgB,EAAE,QAAkB;QACnD,OAAO,IAAI,CAAC,QAAQ,CAAC,UAAU,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;IACrD,CAAC;IAED;;OAEG;IACH,MAAM;QACJ,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IACtB,CAAC;IAED;;;;;;OAMG;IACH,QAAQ;QACN,IAAI,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;QAEvB,KAAK,MAAM,MAAM,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;YAClC,MAAM,CAAC,GAAG,EAAE,CAAC;QACf,CAAC;QAED,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC;IACvB,CAAC;IAEO,IAAI,CAAC,KAAa;QACxB,KAAK,MAAM,MAAM,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;YAClC,MAAM,CAAC,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC;QAClC,CAAC;IACH,CAAC;CACF"}
@@ -0,0 +1,42 @@
1
+ import { SimLiveReload } from "./sim-live-reload.js";
2
+ import { type SimWatchRuntime } from "../../../watch/sim-watch-runtime.js";
3
+ interface SimLocalLiveReloadProperties {
4
+ readonly enabled: boolean;
5
+ readonly watch?: SimWatchRuntime;
6
+ }
7
+ /**
8
+ * Live reload as the local server has to hold it: on or off, and wired into the
9
+ * server's own lifecycle either way.
10
+ *
11
+ * Keeping it here leaves `SimAwsLocalServer` with sockets and ports, which is
12
+ * enough for one class, and puts the three things that only matter together in
13
+ * one place: whether it is on, the notice given on startup, and the warning
14
+ * from a `yulin watch` supervisor that the process is about to be replaced.
15
+ */
16
+ export declare class SimLocalLiveReload {
17
+ private readonly liveReload;
18
+ private readonly watch;
19
+ private readonly onSupervisorStopping;
20
+ constructor(properties: SimLocalLiveReloadProperties);
21
+ /**
22
+ * The channel to hand to the request handler, if there is one.
23
+ */
24
+ channel(): SimLiveReload | undefined;
25
+ /**
26
+ * Say live reload is on, and start listening for a supervised restart.
27
+ *
28
+ * Under `yulin watch` the process is killed rather than asked to close, so
29
+ * this is where a served page finds out a restart is coming.
30
+ */
31
+ serving(port: string): void;
32
+ /**
33
+ * Tell connected browsers a reload is coming, and stop listening.
34
+ */
35
+ stopping(): void;
36
+ /**
37
+ * Reload connected browsers now.
38
+ */
39
+ reload(): void;
40
+ }
41
+ export {};
42
+ //# sourceMappingURL=sim-local-live-reload.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sim-local-live-reload.d.ts","sourceRoot":"","sources":["../../../../src/serve/http/live-reload/sim-local-live-reload.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAErD,OAAO,EAEL,KAAK,eAAe,EACrB,MAAM,qCAAqC,CAAC;AAE7C,UAAU,4BAA4B;IACpC,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAC1B,QAAQ,CAAC,KAAK,CAAC,EAAE,eAAe,CAAC;CAClC;AAED;;;;;;;;GAQG;AACH,qBAAa,kBAAkB;IAC7B,OAAO,CAAC,QAAQ,CAAC,UAAU,CAA4B;IACvD,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAkB;IAExC,OAAO,CAAC,QAAQ,CAAC,oBAAoB,CAEnC;IAEF,YAAY,UAAU,EAAE,4BAA4B,EAInD;IAED;;OAEG;IACH,OAAO,IAAI,aAAa,GAAG,SAAS,CAEnC;IAED;;;;;OAKG;IACH,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAO1B;IAED;;OAEG;IACH,QAAQ,IAAI,IAAI,CAGf;IAED;;OAEG;IACH,MAAM,IAAI,IAAI,CAQb;CACF"}
@@ -0,0 +1,60 @@
1
+ import { SimLiveReload } from "./sim-live-reload.js";
2
+ import { SimLiveReloadReport } from "./sim-live-reload-report.js";
3
+ import { simWatch, } from "../../../watch/sim-watch-runtime.js";
4
+ /**
5
+ * Live reload as the local server has to hold it: on or off, and wired into the
6
+ * server's own lifecycle either way.
7
+ *
8
+ * Keeping it here leaves `SimAwsLocalServer` with sockets and ports, which is
9
+ * enough for one class, and puts the three things that only matter together in
10
+ * one place: whether it is on, the notice given on startup, and the warning
11
+ * from a `yulin watch` supervisor that the process is about to be replaced.
12
+ */
13
+ export class SimLocalLiveReload {
14
+ liveReload;
15
+ watch;
16
+ onSupervisorStopping = () => {
17
+ this.liveReload?.stopping();
18
+ };
19
+ constructor(properties) {
20
+ const { enabled, watch = simWatch } = properties;
21
+ this.liveReload = enabled ? new SimLiveReload() : undefined;
22
+ this.watch = watch;
23
+ }
24
+ /**
25
+ * The channel to hand to the request handler, if there is one.
26
+ */
27
+ channel() {
28
+ return this.liveReload;
29
+ }
30
+ /**
31
+ * Say live reload is on, and start listening for a supervised restart.
32
+ *
33
+ * Under `yulin watch` the process is killed rather than asked to close, so
34
+ * this is where a served page finds out a restart is coming.
35
+ */
36
+ serving(port) {
37
+ if (this.liveReload === undefined) {
38
+ return;
39
+ }
40
+ new SimLiveReloadReport().announce(port);
41
+ this.watch.onStopping(this.onSupervisorStopping);
42
+ }
43
+ /**
44
+ * Tell connected browsers a reload is coming, and stop listening.
45
+ */
46
+ stopping() {
47
+ this.watch.offStopping(this.onSupervisorStopping);
48
+ this.liveReload?.stopping();
49
+ }
50
+ /**
51
+ * Reload connected browsers now.
52
+ */
53
+ reload() {
54
+ if (this.liveReload === undefined) {
55
+ throw new Error("Live reload is off for this server, serve with { liveReload: true } to use reload()");
56
+ }
57
+ this.liveReload.reload();
58
+ }
59
+ }
60
+ //# sourceMappingURL=sim-local-live-reload.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sim-local-live-reload.js","sourceRoot":"","sources":["../../../../src/serve/http/live-reload/sim-local-live-reload.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,EAAE,mBAAmB,EAAE,MAAM,6BAA6B,CAAC;AAClE,OAAO,EACL,QAAQ,GAET,MAAM,qCAAqC,CAAC;AAO7C;;;;;;;;GAQG;AACH,MAAM,OAAO,kBAAkB;IACZ,UAAU,CAA4B;IACtC,KAAK,CAAkB;IAEvB,oBAAoB,GAAG,GAAS,EAAE;QACjD,IAAI,CAAC,UAAU,EAAE,QAAQ,EAAE,CAAC;IAC9B,CAAC,CAAC;IAEF,YAAY,UAAwC;QAClD,MAAM,EAAE,OAAO,EAAE,KAAK,GAAG,QAAQ,EAAE,GAAG,UAAU,CAAC;QACjD,IAAI,CAAC,UAAU,GAAG,OAAO,CAAC,CAAC,CAAC,IAAI,aAAa,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC;QAC5D,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;IACrB,CAAC;IAED;;OAEG;IACH,OAAO;QACL,OAAO,IAAI,CAAC,UAAU,CAAC;IACzB,CAAC;IAED;;;;;OAKG;IACH,OAAO,CAAC,IAAY;QAClB,IAAI,IAAI,CAAC,UAAU,KAAK,SAAS,EAAE,CAAC;YAClC,OAAO;QACT,CAAC;QAED,IAAI,mBAAmB,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;QACzC,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,IAAI,CAAC,oBAAoB,CAAC,CAAC;IACnD,CAAC;IAED;;OAEG;IACH,QAAQ;QACN,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,IAAI,CAAC,oBAAoB,CAAC,CAAC;QAClD,IAAI,CAAC,UAAU,EAAE,QAAQ,EAAE,CAAC;IAC9B,CAAC;IAED;;OAEG;IACH,MAAM;QACJ,IAAI,IAAI,CAAC,UAAU,KAAK,SAAS,EAAE,CAAC;YAClC,MAAM,IAAI,KAAK,CACb,qFAAqF,CACtF,CAAC;QACJ,CAAC;QAED,IAAI,CAAC,UAAU,CAAC,MAAM,EAAE,CAAC;IAC3B,CAAC;CACF"}