kibi-swipl-linux-x64-gnu 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.
Files changed (550) hide show
  1. package/README.md +29 -0
  2. package/bin/swipl +0 -0
  3. package/bin/swipl-win +0 -0
  4. package/build-manifest.json +70 -0
  5. package/lib/cmake/swipl/SWIPLConfig.cmake +21 -0
  6. package/lib/cmake/swipl/SWIPLConfigVersion.cmake +65 -0
  7. package/lib/cmake/swipl/SWIPLTargets-release.cmake +28 -0
  8. package/lib/cmake/swipl/SWIPLTargets.cmake +109 -0
  9. package/lib/swipl/ABI +1 -0
  10. package/lib/swipl/LICENSE +41 -0
  11. package/lib/swipl/README.md +116 -0
  12. package/lib/swipl/app/README.md +25 -0
  13. package/lib/swipl/app/app.pl +87 -0
  14. package/lib/swipl/app/pack.pl +350 -0
  15. package/lib/swipl/app/qlf.pl +521 -0
  16. package/lib/swipl/app/splfr.pl +177 -0
  17. package/lib/swipl/app/sys.pl +310 -0
  18. package/lib/swipl/bin/swipl.home +1 -0
  19. package/lib/swipl/boot/apply.pl +73 -0
  20. package/lib/swipl/boot/attvar.pl +344 -0
  21. package/lib/swipl/boot/autoload.pl +1226 -0
  22. package/lib/swipl/boot/bags.pl +283 -0
  23. package/lib/swipl/boot/dcg.pl +388 -0
  24. package/lib/swipl/boot/dicts.pl +193 -0
  25. package/lib/swipl/boot/dwim.pl +485 -0
  26. package/lib/swipl/boot/engines.pl +152 -0
  27. package/lib/swipl/boot/expand.pl +1628 -0
  28. package/lib/swipl/boot/gc.pl +65 -0
  29. package/lib/swipl/boot/history.pl +304 -0
  30. package/lib/swipl/boot/init.pl +4682 -0
  31. package/lib/swipl/boot/iri.pl +64 -0
  32. package/lib/swipl/boot/license.pl +390 -0
  33. package/lib/swipl/boot/load.pl +81 -0
  34. package/lib/swipl/boot/messages.pl +2521 -0
  35. package/lib/swipl/boot/packs.pl +306 -0
  36. package/lib/swipl/boot/predopts.pl +154 -0
  37. package/lib/swipl/boot/qlf.pl +141 -0
  38. package/lib/swipl/boot/rc.pl +263 -0
  39. package/lib/swipl/boot/syspred.pl +1634 -0
  40. package/lib/swipl/boot/tabling.pl +2321 -0
  41. package/lib/swipl/boot/threads.pl +42 -0
  42. package/lib/swipl/boot/toplevel.pl +2248 -0
  43. package/lib/swipl/boot/topvars.pl +261 -0
  44. package/lib/swipl/boot.prc +0 -0
  45. package/lib/swipl/cmake/swipl.cmake +131 -0
  46. package/lib/swipl/customize/README.md +23 -0
  47. package/lib/swipl/customize/edit +101 -0
  48. package/lib/swipl/customize/init.pl +164 -0
  49. package/lib/swipl/demo/README.md +33 -0
  50. package/lib/swipl/demo/likes.pl +44 -0
  51. package/lib/swipl/doc/packages/examples/chr/bool.chr +281 -0
  52. package/lib/swipl/doc/packages/examples/chr/chrdif.chr +87 -0
  53. package/lib/swipl/doc/packages/examples/chr/chrfreeze.chr +6 -0
  54. package/lib/swipl/doc/packages/examples/chr/family.chr +116 -0
  55. package/lib/swipl/doc/packages/examples/chr/fib.chr +24 -0
  56. package/lib/swipl/doc/packages/examples/chr/fibonacci.chr +31 -0
  57. package/lib/swipl/doc/packages/examples/chr/gcd.chr +28 -0
  58. package/lib/swipl/doc/packages/examples/chr/leq.chr +34 -0
  59. package/lib/swipl/doc/packages/examples/chr/listdom.chr +138 -0
  60. package/lib/swipl/doc/packages/examples/chr/primes.chr +29 -0
  61. package/lib/swipl/doc/packages/examples/http/README.md +98 -0
  62. package/lib/swipl/doc/packages/examples/http/calc.pl +92 -0
  63. package/lib/swipl/doc/packages/examples/http/demo_body.pl +232 -0
  64. package/lib/swipl/doc/packages/examples/http/demo_client.pl +165 -0
  65. package/lib/swipl/doc/packages/examples/http/demo_daemon.pl +38 -0
  66. package/lib/swipl/doc/packages/examples/http/demo_files.pl +50 -0
  67. package/lib/swipl/doc/packages/examples/http/demo_hello.pl +15 -0
  68. package/lib/swipl/doc/packages/examples/http/demo_login.pl +280 -0
  69. package/lib/swipl/doc/packages/examples/http/demo_openid.pl +177 -0
  70. package/lib/swipl/doc/packages/examples/http/demo_pwp.pl +20 -0
  71. package/lib/swipl/doc/packages/examples/http/demo_rest.pl +56 -0
  72. package/lib/swipl/doc/packages/examples/http/demo_threads.pl +52 -0
  73. package/lib/swipl/doc/packages/examples/http/linux-init-script +126 -0
  74. package/lib/swipl/doc/packages/examples/http/pwp/context.pwp +23 -0
  75. package/lib/swipl/doc/packages/examples/http/pwp/index.pwp +25 -0
  76. package/lib/swipl/doc/packages/examples/http/pwp/pwp1.pwp +12 -0
  77. package/lib/swipl/doc/packages/examples/http/pwp/pwp2.pwp +10 -0
  78. package/lib/swipl/doc/packages/examples/http/pwp/pwp3.pwp +25 -0
  79. package/lib/swipl/doc/packages/examples/http/pwp/pwp4.pwp +23 -0
  80. package/lib/swipl/doc/packages/examples/http/pwp/pwp5.pwp +11 -0
  81. package/lib/swipl/doc/packages/examples/http/pwp/pwp6.pwp +3 -0
  82. package/lib/swipl/doc/packages/examples/http/pwp/pwp7.pwp +3 -0
  83. package/lib/swipl/doc/packages/examples/http/pwp/pwp8.pwp +3 -0
  84. package/lib/swipl/doc/packages/examples/http/pwp/pwpdb.pl +12 -0
  85. package/lib/swipl/doc/packages/examples/http/systemd-script.service +18 -0
  86. package/lib/swipl/doc/packages/examples/http/upstart-script.conf +20 -0
  87. package/lib/swipl/doc/packages/examples/plunit/read.pl +17 -0
  88. package/lib/swipl/doc/packages/examples/plunit/simple.pl +33 -0
  89. package/lib/swipl/doc/packages/examples/ssl/client.pl +83 -0
  90. package/lib/swipl/doc/packages/examples/ssl/etc/README +52 -0
  91. package/lib/swipl/doc/packages/examples/ssl/etc/client/client-cert.p12 +0 -0
  92. package/lib/swipl/doc/packages/examples/ssl/etc/client/client-cert.pem +85 -0
  93. package/lib/swipl/doc/packages/examples/ssl/etc/client/client-key.pem +30 -0
  94. package/lib/swipl/doc/packages/examples/ssl/etc/demoCA/cacert.pem +82 -0
  95. package/lib/swipl/doc/packages/examples/ssl/etc/demoCA/careq.pem +18 -0
  96. package/lib/swipl/doc/packages/examples/ssl/etc/demoCA/crlnumber +1 -0
  97. package/lib/swipl/doc/packages/examples/ssl/etc/demoCA/index.txt +3 -0
  98. package/lib/swipl/doc/packages/examples/ssl/etc/demoCA/index.txt.attr +1 -0
  99. package/lib/swipl/doc/packages/examples/ssl/etc/demoCA/newcerts/9DC08797A0F63F7C.pem +85 -0
  100. package/lib/swipl/doc/packages/examples/ssl/etc/demoCA/newcerts/9DC08797A0F63F7D.pem +85 -0
  101. package/lib/swipl/doc/packages/examples/ssl/etc/demoCA/private/cakey.pem +30 -0
  102. package/lib/swipl/doc/packages/examples/ssl/etc/demoCA/serial +1 -0
  103. package/lib/swipl/doc/packages/examples/ssl/etc/server/server-cert.pem +85 -0
  104. package/lib/swipl/doc/packages/examples/ssl/etc/server/server-key.pem +30 -0
  105. package/lib/swipl/doc/packages/examples/ssl/https.pl +267 -0
  106. package/lib/swipl/doc/packages/examples/ssl/server.pl +106 -0
  107. package/lib/swipl/include/SWI-Prolog.h +1544 -0
  108. package/lib/swipl/include/SWI-Stream.h +537 -0
  109. package/lib/swipl/include/Yap/YapInterface.h +283 -0
  110. package/lib/swipl/include/sicstus/sicstus.h +452 -0
  111. package/lib/swipl/lib/x86_64-linux/cgi.so +0 -0
  112. package/lib/swipl/lib/x86_64-linux/crypt.so +0 -0
  113. package/lib/swipl/lib/x86_64-linux/crypto4pl.so +0 -0
  114. package/lib/swipl/lib/x86_64-linux/double_metaphone.so +0 -0
  115. package/lib/swipl/lib/x86_64-linux/files.so +0 -0
  116. package/lib/swipl/lib/x86_64-linux/hashstream.so +0 -0
  117. package/lib/swipl/lib/x86_64-linux/http_stream.so +0 -0
  118. package/lib/swipl/lib/x86_64-linux/isub.so +0 -0
  119. package/lib/swipl/lib/x86_64-linux/json.so +0 -0
  120. package/lib/swipl/lib/x86_64-linux/libswipl.so.10 +0 -0
  121. package/lib/swipl/lib/x86_64-linux/mallocinfo.so +0 -0
  122. package/lib/swipl/lib/x86_64-linux/md54pl.so +0 -0
  123. package/lib/swipl/lib/x86_64-linux/memfile.so +0 -0
  124. package/lib/swipl/lib/x86_64-linux/ntriples.so +0 -0
  125. package/lib/swipl/lib/x86_64-linux/pcre4pl.so +0 -0
  126. package/lib/swipl/lib/x86_64-linux/porter_stem.so +0 -0
  127. package/lib/swipl/lib/x86_64-linux/process.so +0 -0
  128. package/lib/swipl/lib/x86_64-linux/prolog_stream.so +0 -0
  129. package/lib/swipl/lib/x86_64-linux/rdf_db.so +0 -0
  130. package/lib/swipl/lib/x86_64-linux/readutil.so +0 -0
  131. package/lib/swipl/lib/x86_64-linux/rlimit.so +0 -0
  132. package/lib/swipl/lib/x86_64-linux/sched.so +0 -0
  133. package/lib/swipl/lib/x86_64-linux/sgml2pl.so +0 -0
  134. package/lib/swipl/lib/x86_64-linux/sha4pl.so +0 -0
  135. package/lib/swipl/lib/x86_64-linux/snowball.so +0 -0
  136. package/lib/swipl/lib/x86_64-linux/socket.so +0 -0
  137. package/lib/swipl/lib/x86_64-linux/ssl4pl.so +0 -0
  138. package/lib/swipl/lib/x86_64-linux/streaminfo.so +0 -0
  139. package/lib/swipl/lib/x86_64-linux/syslog.so +0 -0
  140. package/lib/swipl/lib/x86_64-linux/time.so +0 -0
  141. package/lib/swipl/lib/x86_64-linux/turtle.so +0 -0
  142. package/lib/swipl/lib/x86_64-linux/uid.so +0 -0
  143. package/lib/swipl/lib/x86_64-linux/unix.so +0 -0
  144. package/lib/swipl/lib/x86_64-linux/uri.so +0 -0
  145. package/lib/swipl/lib/x86_64-linux/websocket.so +0 -0
  146. package/lib/swipl/lib/x86_64-linux/zlib4pl.so +0 -0
  147. package/lib/swipl/library/INDEX.pl +1020 -0
  148. package/lib/swipl/library/aggregate.pl +755 -0
  149. package/lib/swipl/library/ansi_term.pl +653 -0
  150. package/lib/swipl/library/apply.pl +426 -0
  151. package/lib/swipl/library/apply_macros.pl +497 -0
  152. package/lib/swipl/library/arithmetic.pl +320 -0
  153. package/lib/swipl/library/assoc.pl +522 -0
  154. package/lib/swipl/library/atom.pl +169 -0
  155. package/lib/swipl/library/backcomp.pl +688 -0
  156. package/lib/swipl/library/base32.pl +291 -0
  157. package/lib/swipl/library/base64.pl +441 -0
  158. package/lib/swipl/library/broadcast.pl +161 -0
  159. package/lib/swipl/library/build/cmake.pl +137 -0
  160. package/lib/swipl/library/build/conan.pl +232 -0
  161. package/lib/swipl/library/build/make.pl +168 -0
  162. package/lib/swipl/library/build/tools.pl +825 -0
  163. package/lib/swipl/library/charsio.pl +195 -0
  164. package/lib/swipl/library/check.pl +1097 -0
  165. package/lib/swipl/library/check_installation.pl +912 -0
  166. package/lib/swipl/library/clp/INDEX.pl +157 -0
  167. package/lib/swipl/library/clp/bounds.pl +2036 -0
  168. package/lib/swipl/library/clp/clp_distinct.pl +263 -0
  169. package/lib/swipl/library/clp/clp_events.pl +92 -0
  170. package/lib/swipl/library/clp/clpb.pl +1896 -0
  171. package/lib/swipl/library/clp/clpfd.pl +7906 -0
  172. package/lib/swipl/library/clp/simplex.pl +1580 -0
  173. package/lib/swipl/library/codesio.pl +182 -0
  174. package/lib/swipl/library/coinduction.pl +183 -0
  175. package/lib/swipl/library/console_input.pl +289 -0
  176. package/lib/swipl/library/csv.pl +611 -0
  177. package/lib/swipl/library/ctypes.pl +161 -0
  178. package/lib/swipl/library/date.pl +370 -0
  179. package/lib/swipl/library/dcg/INDEX.pl +35 -0
  180. package/lib/swipl/library/dcg/basics.pl +514 -0
  181. package/lib/swipl/library/dcg/high_order.pl +227 -0
  182. package/lib/swipl/library/debug.pl +499 -0
  183. package/lib/swipl/library/dialect/bim.pl +186 -0
  184. package/lib/swipl/library/dialect/commons.pl +77 -0
  185. package/lib/swipl/library/dialect/eclipse/test_util_iso.pl +355 -0
  186. package/lib/swipl/library/dialect/hprolog/format.pl +44 -0
  187. package/lib/swipl/library/dialect/hprolog.pl +314 -0
  188. package/lib/swipl/library/dialect/ifprolog.pl +1317 -0
  189. package/lib/swipl/library/dialect/iso/iso_predicates.pl +277 -0
  190. package/lib/swipl/library/dialect/sicstus/README.TXT +1 -0
  191. package/lib/swipl/library/dialect/sicstus/arrays.pl +121 -0
  192. package/lib/swipl/library/dialect/sicstus/block.pl +278 -0
  193. package/lib/swipl/library/dialect/sicstus/lists.pl +167 -0
  194. package/lib/swipl/library/dialect/sicstus/ordsets.pl +52 -0
  195. package/lib/swipl/library/dialect/sicstus/sockets.pl +174 -0
  196. package/lib/swipl/library/dialect/sicstus/system.pl +262 -0
  197. package/lib/swipl/library/dialect/sicstus/terms.pl +57 -0
  198. package/lib/swipl/library/dialect/sicstus/timeout.pl +92 -0
  199. package/lib/swipl/library/dialect/sicstus.pl +582 -0
  200. package/lib/swipl/library/dialect/sicstus4/aggregate.pl +60 -0
  201. package/lib/swipl/library/dialect/sicstus4/between.pl +62 -0
  202. package/lib/swipl/library/dialect/sicstus4/clpfd.pl +75 -0
  203. package/lib/swipl/library/dialect/sicstus4/file_systems.pl +413 -0
  204. package/lib/swipl/library/dialect/sicstus4/lists.pl +274 -0
  205. package/lib/swipl/library/dialect/sicstus4/ordsets.pl +54 -0
  206. package/lib/swipl/library/dialect/sicstus4/samsort.pl +86 -0
  207. package/lib/swipl/library/dialect/sicstus4/sets.pl +124 -0
  208. package/lib/swipl/library/dialect/sicstus4/sockets.pl +164 -0
  209. package/lib/swipl/library/dialect/sicstus4/system.pl +80 -0
  210. package/lib/swipl/library/dialect/sicstus4/terms.pl +89 -0
  211. package/lib/swipl/library/dialect/sicstus4/timeout.pl +43 -0
  212. package/lib/swipl/library/dialect/sicstus4/types.pl +103 -0
  213. package/lib/swipl/library/dialect/sicstus4.pl +200 -0
  214. package/lib/swipl/library/dialect/swi/syspred_options.pl +250 -0
  215. package/lib/swipl/library/dialect/xsb/README.md +20 -0
  216. package/lib/swipl/library/dialect/xsb/basics.pl +318 -0
  217. package/lib/swipl/library/dialect/xsb/consult.pl +87 -0
  218. package/lib/swipl/library/dialect/xsb/curr_sym.pl +57 -0
  219. package/lib/swipl/library/dialect/xsb/error_handler.pl +111 -0
  220. package/lib/swipl/library/dialect/xsb/gensym.pl +53 -0
  221. package/lib/swipl/library/dialect/xsb/gpp.pl +138 -0
  222. package/lib/swipl/library/dialect/xsb/intern.pl +48 -0
  223. package/lib/swipl/library/dialect/xsb/lists.pl +47 -0
  224. package/lib/swipl/library/dialect/xsb/machine.pl +295 -0
  225. package/lib/swipl/library/dialect/xsb/ordsets.pl +53 -0
  226. package/lib/swipl/library/dialect/xsb/setof.pl +54 -0
  227. package/lib/swipl/library/dialect/xsb/source.pl +308 -0
  228. package/lib/swipl/library/dialect/xsb/standard.pl +169 -0
  229. package/lib/swipl/library/dialect/xsb/storage.pl +70 -0
  230. package/lib/swipl/library/dialect/xsb/string.pl +76 -0
  231. package/lib/swipl/library/dialect/xsb/thread.pl +62 -0
  232. package/lib/swipl/library/dialect/xsb/timed_call.pl +158 -0
  233. package/lib/swipl/library/dialect/xsb.pl +688 -0
  234. package/lib/swipl/library/dialect/yap/README.TXT +8 -0
  235. package/lib/swipl/library/dialect/yap.pl +283 -0
  236. package/lib/swipl/library/dialect.pl +123 -0
  237. package/lib/swipl/library/dicts.pl +399 -0
  238. package/lib/swipl/library/dif.pl +426 -0
  239. package/lib/swipl/library/edinburgh.pl +138 -0
  240. package/lib/swipl/library/edit.pl +783 -0
  241. package/lib/swipl/library/error.pl +495 -0
  242. package/lib/swipl/library/exceptions.pl +231 -0
  243. package/lib/swipl/library/explain.pl +543 -0
  244. package/lib/swipl/library/ext/RDF/INDEX.pl +25 -0
  245. package/lib/swipl/library/ext/RDF/rdf.pl +450 -0
  246. package/lib/swipl/library/ext/RDF/rdf_parser.pl +649 -0
  247. package/lib/swipl/library/ext/RDF/rdf_triple.pl +448 -0
  248. package/lib/swipl/library/ext/RDF/rdf_write.pl +701 -0
  249. package/lib/swipl/library/ext/RDF/rewrite_term.pl +177 -0
  250. package/lib/swipl/library/ext/chr/chr/a_star.pl +80 -0
  251. package/lib/swipl/library/ext/chr/chr/binomialheap.pl +142 -0
  252. package/lib/swipl/library/ext/chr/chr/builtins.pl +629 -0
  253. package/lib/swipl/library/ext/chr/chr/chr_compiler_errors.pl +179 -0
  254. package/lib/swipl/library/ext/chr/chr/chr_compiler_options.pl +382 -0
  255. package/lib/swipl/library/ext/chr/chr/chr_compiler_utility.pl +338 -0
  256. package/lib/swipl/library/ext/chr/chr/chr_debug.pl +59 -0
  257. package/lib/swipl/library/ext/chr/chr/chr_hashtable_store.pl +425 -0
  258. package/lib/swipl/library/ext/chr/chr/chr_integertable_store.pl +139 -0
  259. package/lib/swipl/library/ext/chr/chr/chr_messages.pl +176 -0
  260. package/lib/swipl/library/ext/chr/chr/chr_op.pl +53 -0
  261. package/lib/swipl/library/ext/chr/chr/chr_runtime.pl +1016 -0
  262. package/lib/swipl/library/ext/chr/chr/chr_translate.pl +25424 -0
  263. package/lib/swipl/library/ext/chr/chr/clean_code.pl +252 -0
  264. package/lib/swipl/library/ext/chr/chr/find.pl +78 -0
  265. package/lib/swipl/library/ext/chr/chr/guard_entailment.pl +19432 -0
  266. package/lib/swipl/library/ext/chr/chr/listmap.pl +108 -0
  267. package/lib/swipl/library/ext/chr/chr/pairlist.pl +78 -0
  268. package/lib/swipl/library/ext/chr/chr.pl +686 -0
  269. package/lib/swipl/library/ext/clib/INDEX.pl +158 -0
  270. package/lib/swipl/library/ext/clib/cgi.pl +86 -0
  271. package/lib/swipl/library/ext/clib/crypt.pl +44 -0
  272. package/lib/swipl/library/ext/clib/filesex.pl +644 -0
  273. package/lib/swipl/library/ext/clib/hash_stream.pl +119 -0
  274. package/lib/swipl/library/ext/clib/mallocinfo.pl +138 -0
  275. package/lib/swipl/library/ext/clib/md5.pl +68 -0
  276. package/lib/swipl/library/ext/clib/memfile.pl +61 -0
  277. package/lib/swipl/library/ext/clib/process.pl +573 -0
  278. package/lib/swipl/library/ext/clib/prolog_server.pl +157 -0
  279. package/lib/swipl/library/ext/clib/prolog_stream.pl +80 -0
  280. package/lib/swipl/library/ext/clib/rlimit.pl +54 -0
  281. package/lib/swipl/library/ext/clib/sched.pl +85 -0
  282. package/lib/swipl/library/ext/clib/sha.pl +162 -0
  283. package/lib/swipl/library/ext/clib/socket.pl +1102 -0
  284. package/lib/swipl/library/ext/clib/streaminfo.pl +103 -0
  285. package/lib/swipl/library/ext/clib/streampool.pl +136 -0
  286. package/lib/swipl/library/ext/clib/syslog.pl +180 -0
  287. package/lib/swipl/library/ext/clib/time.pl +194 -0
  288. package/lib/swipl/library/ext/clib/udp_broadcast.pl +975 -0
  289. package/lib/swipl/library/ext/clib/uid.pl +220 -0
  290. package/lib/swipl/library/ext/clib/unix.pl +317 -0
  291. package/lib/swipl/library/ext/clib/uri.pl +530 -0
  292. package/lib/swipl/library/ext/clib/uuid.pl +207 -0
  293. package/lib/swipl/library/ext/http/http/INDEX.pl +266 -0
  294. package/lib/swipl/library/ext/http/http/README.md +34 -0
  295. package/lib/swipl/library/ext/http/http/ax.pl +189 -0
  296. package/lib/swipl/library/ext/http/http/dcg_basics.pl +49 -0
  297. package/lib/swipl/library/ext/http/http/graphql.pl +1367 -0
  298. package/lib/swipl/library/ext/http/http/html_decl.pl +416 -0
  299. package/lib/swipl/library/ext/http/http/html_head.pl +654 -0
  300. package/lib/swipl/library/ext/http/http/html_quasiquotations.pl +120 -0
  301. package/lib/swipl/library/ext/http/http/html_write.pl +1425 -0
  302. package/lib/swipl/library/ext/http/http/htmx.pl +139 -0
  303. package/lib/swipl/library/ext/http/http/http_authenticate.pl +364 -0
  304. package/lib/swipl/library/ext/http/http/http_client.pl +412 -0
  305. package/lib/swipl/library/ext/http/http/http_cookie.pl +245 -0
  306. package/lib/swipl/library/ext/http/http/http_cors.pl +176 -0
  307. package/lib/swipl/library/ext/http/http/http_digest.pl +820 -0
  308. package/lib/swipl/library/ext/http/http/http_dirindex.pl +296 -0
  309. package/lib/swipl/library/ext/http/http/http_dispatch.pl +1552 -0
  310. package/lib/swipl/library/ext/http/http/http_dyn_workers.pl +214 -0
  311. package/lib/swipl/library/ext/http/http/http_error.pl +126 -0
  312. package/lib/swipl/library/ext/http/http/http_exception.pl +225 -0
  313. package/lib/swipl/library/ext/http/http/http_files.pl +163 -0
  314. package/lib/swipl/library/ext/http/http/http_header.pl +2820 -0
  315. package/lib/swipl/library/ext/http/http/http_hook.pl +106 -0
  316. package/lib/swipl/library/ext/http/http/http_host.pl +204 -0
  317. package/lib/swipl/library/ext/http/http/http_load.pl +113 -0
  318. package/lib/swipl/library/ext/http/http/http_log.pl +738 -0
  319. package/lib/swipl/library/ext/http/http/http_multipart_plugin.pl +232 -0
  320. package/lib/swipl/library/ext/http/http/http_open.pl +1821 -0
  321. package/lib/swipl/library/ext/http/http/http_openid.pl +1561 -0
  322. package/lib/swipl/library/ext/http/http/http_parameters.pl +504 -0
  323. package/lib/swipl/library/ext/http/http/http_path.pl +380 -0
  324. package/lib/swipl/library/ext/http/http/http_proxy.pl +80 -0
  325. package/lib/swipl/library/ext/http/http/http_pwp.pl +351 -0
  326. package/lib/swipl/library/ext/http/http/http_redis_plugin.pl +332 -0
  327. package/lib/swipl/library/ext/http/http/http_server.pl +105 -0
  328. package/lib/swipl/library/ext/http/http/http_server_files.pl +126 -0
  329. package/lib/swipl/library/ext/http/http/http_server_health.pl +186 -0
  330. package/lib/swipl/library/ext/http/http/http_session.pl +1040 -0
  331. package/lib/swipl/library/ext/http/http/http_sgml_plugin.pl +137 -0
  332. package/lib/swipl/library/ext/http/http/http_stream.pl +376 -0
  333. package/lib/swipl/library/ext/http/http/http_unix_daemon.pl +989 -0
  334. package/lib/swipl/library/ext/http/http/http_wrapper.pl +559 -0
  335. package/lib/swipl/library/ext/http/http/hub.pl +600 -0
  336. package/lib/swipl/library/ext/http/http/js_write.pl +461 -0
  337. package/lib/swipl/library/ext/http/http/mimepack.pl +224 -0
  338. package/lib/swipl/library/ext/http/http/mimetype.pl +276 -0
  339. package/lib/swipl/library/ext/http/http/term_html.pl +797 -0
  340. package/lib/swipl/library/ext/http/http/thread_httpd.pl +1181 -0
  341. package/lib/swipl/library/ext/http/http/web/css/dirindex.css +24 -0
  342. package/lib/swipl/library/ext/http/http/web/css/openid.css +57 -0
  343. package/lib/swipl/library/ext/http/http/web/icons/back.png +0 -0
  344. package/lib/swipl/library/ext/http/http/web/icons/c.png +0 -0
  345. package/lib/swipl/library/ext/http/http/web/icons/compressed.png +0 -0
  346. package/lib/swipl/library/ext/http/http/web/icons/folder.png +0 -0
  347. package/lib/swipl/library/ext/http/http/web/icons/generic.png +0 -0
  348. package/lib/swipl/library/ext/http/http/web/icons/layout.png +0 -0
  349. package/lib/swipl/library/ext/http/http/web/icons/openid-logo-square.png +0 -0
  350. package/lib/swipl/library/ext/http/http/web/icons/openid-logo-tiny.png +0 -0
  351. package/lib/swipl/library/ext/http/http/websocket.pl +729 -0
  352. package/lib/swipl/library/ext/http/http/yadis.pl +205 -0
  353. package/lib/swipl/library/ext/json/INDEX.pl +36 -0
  354. package/lib/swipl/library/ext/json/http/INDEX.pl +16 -0
  355. package/lib/swipl/library/ext/json/http/http_json.pl +490 -0
  356. package/lib/swipl/library/ext/json/http/js_grammar.pl +53 -0
  357. package/lib/swipl/library/ext/json/http/json.pl +48 -0
  358. package/lib/swipl/library/ext/json/http/json_convert.pl +48 -0
  359. package/lib/swipl/library/ext/json/json.pl +1215 -0
  360. package/lib/swipl/library/ext/json/json_convert.pl +681 -0
  361. package/lib/swipl/library/ext/json/json_grammar.pl +349 -0
  362. package/lib/swipl/library/ext/json/json_rpc_client.pl +423 -0
  363. package/lib/swipl/library/ext/json/json_rpc_common.pl +104 -0
  364. package/lib/swipl/library/ext/json/json_rpc_server.pl +489 -0
  365. package/lib/swipl/library/ext/json/json_schema.pl +2111 -0
  366. package/lib/swipl/library/ext/nlp/INDEX.pl +15 -0
  367. package/lib/swipl/library/ext/nlp/double_metaphone.pl +86 -0
  368. package/lib/swipl/library/ext/nlp/isub.pl +162 -0
  369. package/lib/swipl/library/ext/nlp/porter_stem.pl +50 -0
  370. package/lib/swipl/library/ext/nlp/snowball.pl +97 -0
  371. package/lib/swipl/library/ext/pcre/INDEX.pl +17 -0
  372. package/lib/swipl/library/ext/pcre/pcre.pl +974 -0
  373. package/lib/swipl/library/ext/plunit/INDEX.pl +20 -0
  374. package/lib/swipl/library/ext/plunit/plunit.pl +2631 -0
  375. package/lib/swipl/library/ext/plunit/test_wizard.pl +249 -0
  376. package/lib/swipl/library/ext/semweb/semweb/INDEX.pl +288 -0
  377. package/lib/swipl/library/ext/semweb/semweb/rdf11.pl +2106 -0
  378. package/lib/swipl/library/ext/semweb/semweb/rdf11_containers.pl +299 -0
  379. package/lib/swipl/library/ext/semweb/semweb/rdf_cache.pl +278 -0
  380. package/lib/swipl/library/ext/semweb/semweb/rdf_compare.pl +132 -0
  381. package/lib/swipl/library/ext/semweb/semweb/rdf_db.pl +3468 -0
  382. package/lib/swipl/library/ext/semweb/semweb/rdf_edit.pl +1145 -0
  383. package/lib/swipl/library/ext/semweb/semweb/rdf_http_plugin.pl +274 -0
  384. package/lib/swipl/library/ext/semweb/semweb/rdf_library.pl +1021 -0
  385. package/lib/swipl/library/ext/semweb/semweb/rdf_litindex.pl +1035 -0
  386. package/lib/swipl/library/ext/semweb/semweb/rdf_ntriples.pl +422 -0
  387. package/lib/swipl/library/ext/semweb/semweb/rdf_persistency.pl +1576 -0
  388. package/lib/swipl/library/ext/semweb/semweb/rdf_portray.pl +182 -0
  389. package/lib/swipl/library/ext/semweb/semweb/rdf_prefixes.pl +681 -0
  390. package/lib/swipl/library/ext/semweb/semweb/rdf_sandbox.pl +153 -0
  391. package/lib/swipl/library/ext/semweb/semweb/rdf_turtle.pl +54 -0
  392. package/lib/swipl/library/ext/semweb/semweb/rdf_turtle_write.pl +1587 -0
  393. package/lib/swipl/library/ext/semweb/semweb/rdf_zlib_plugin.pl +52 -0
  394. package/lib/swipl/library/ext/semweb/semweb/rdfa.pl +1510 -0
  395. package/lib/swipl/library/ext/semweb/semweb/rdfs.pl +475 -0
  396. package/lib/swipl/library/ext/semweb/semweb/sparql_client.pl +643 -0
  397. package/lib/swipl/library/ext/semweb/semweb/turtle.pl +455 -0
  398. package/lib/swipl/library/ext/sgml/DTD/HTML4.dcl +88 -0
  399. package/lib/swipl/library/ext/sgml/DTD/HTML4.dtd +1092 -0
  400. package/lib/swipl/library/ext/sgml/DTD/HTML4.soc +6 -0
  401. package/lib/swipl/library/ext/sgml/DTD/HTML5.dtd +906 -0
  402. package/lib/swipl/library/ext/sgml/DTD/HTMLlat1.ent +195 -0
  403. package/lib/swipl/library/ext/sgml/DTD/HTMLspec.ent +77 -0
  404. package/lib/swipl/library/ext/sgml/DTD/HTMLsym.ent +241 -0
  405. package/lib/swipl/library/ext/sgml/INDEX.pl +64 -0
  406. package/lib/swipl/library/ext/sgml/c14n2.pl +203 -0
  407. package/lib/swipl/library/ext/sgml/iso_639.pl +631 -0
  408. package/lib/swipl/library/ext/sgml/pwp.pl +705 -0
  409. package/lib/swipl/library/ext/sgml/sgml.pl +815 -0
  410. package/lib/swipl/library/ext/sgml/sgml_write.pl +1003 -0
  411. package/lib/swipl/library/ext/sgml/xpath.pl +620 -0
  412. package/lib/swipl/library/ext/sgml/xsdp_types.pl +232 -0
  413. package/lib/swipl/library/ext/ssl/INDEX.pl +60 -0
  414. package/lib/swipl/library/ext/ssl/crypto.pl +1015 -0
  415. package/lib/swipl/library/ext/ssl/http/INDEX.pl +5 -0
  416. package/lib/swipl/library/ext/ssl/http/http_ssl_plugin.pl +296 -0
  417. package/lib/swipl/library/ext/ssl/saml.pl +609 -0
  418. package/lib/swipl/library/ext/ssl/ssl.pl +647 -0
  419. package/lib/swipl/library/ext/ssl/xmldsig.pl +391 -0
  420. package/lib/swipl/library/ext/ssl/xmlenc.pl +354 -0
  421. package/lib/swipl/library/ext/zlib/INDEX.pl +8 -0
  422. package/lib/swipl/library/ext/zlib/zlib.pl +112 -0
  423. package/lib/swipl/library/fastrw.pl +105 -0
  424. package/lib/swipl/library/files.pl +80 -0
  425. package/lib/swipl/library/gensym.pl +111 -0
  426. package/lib/swipl/library/git.pl +1027 -0
  427. package/lib/swipl/library/hashtable.pl +365 -0
  428. package/lib/swipl/library/heaps.pl +252 -0
  429. package/lib/swipl/library/hotfix.pl +239 -0
  430. package/lib/swipl/library/http/jquery.pl +103 -0
  431. package/lib/swipl/library/http/web/js/jquery-3.6.0.min.js +2 -0
  432. package/lib/swipl/library/increval.pl +217 -0
  433. package/lib/swipl/library/intercept.pl +263 -0
  434. package/lib/swipl/library/iostream.pl +237 -0
  435. package/lib/swipl/library/iri_scheme/file.pl +70 -0
  436. package/lib/swipl/library/lazy_lists.pl +481 -0
  437. package/lib/swipl/library/listing.pl +1362 -0
  438. package/lib/swipl/library/lists.pl +860 -0
  439. package/lib/swipl/library/lynx/INDEX.pl +14 -0
  440. package/lib/swipl/library/lynx/format.pl +380 -0
  441. package/lib/swipl/library/lynx/html_style.pl +129 -0
  442. package/lib/swipl/library/lynx/html_text.pl +865 -0
  443. package/lib/swipl/library/lynx/pldoc_style.pl +87 -0
  444. package/lib/swipl/library/macros.pl +451 -0
  445. package/lib/swipl/library/main.pl +1200 -0
  446. package/lib/swipl/library/make.pl +197 -0
  447. package/lib/swipl/library/modules.pl +129 -0
  448. package/lib/swipl/library/nb_rbtrees.pl +267 -0
  449. package/lib/swipl/library/nb_set.pl +203 -0
  450. package/lib/swipl/library/obfuscate.pl +115 -0
  451. package/lib/swipl/library/occurs.pl +241 -0
  452. package/lib/swipl/library/operators.pl +182 -0
  453. package/lib/swipl/library/option.pl +388 -0
  454. package/lib/swipl/library/optparse.pl +966 -0
  455. package/lib/swipl/library/ordsets.pl +518 -0
  456. package/lib/swipl/library/oset.pl +160 -0
  457. package/lib/swipl/library/pairs.pl +187 -0
  458. package/lib/swipl/library/persistency.pl +713 -0
  459. package/lib/swipl/library/pio.pl +47 -0
  460. package/lib/swipl/library/portray_text.pl +277 -0
  461. package/lib/swipl/library/pprint.pl +940 -0
  462. package/lib/swipl/library/predicate_options.pl +975 -0
  463. package/lib/swipl/library/prolog_autoload.pl +233 -0
  464. package/lib/swipl/library/prolog_breakpoints.pl +396 -0
  465. package/lib/swipl/library/prolog_clause.pl +1104 -0
  466. package/lib/swipl/library/prolog_code.pl +416 -0
  467. package/lib/swipl/library/prolog_codewalk.pl +1248 -0
  468. package/lib/swipl/library/prolog_colour.pl +3301 -0
  469. package/lib/swipl/library/prolog_colour.qlf +0 -0
  470. package/lib/swipl/library/prolog_config.pl +154 -0
  471. package/lib/swipl/library/prolog_coverage.pl +1333 -0
  472. package/lib/swipl/library/prolog_debug.pl +404 -0
  473. package/lib/swipl/library/prolog_deps.pl +675 -0
  474. package/lib/swipl/library/prolog_evaluable.pl +234 -0
  475. package/lib/swipl/library/prolog_format.pl +219 -0
  476. package/lib/swipl/library/prolog_history.pl +161 -0
  477. package/lib/swipl/library/prolog_jiti.pl +333 -0
  478. package/lib/swipl/library/prolog_locale.pl +61 -0
  479. package/lib/swipl/library/prolog_metainference.pl +307 -0
  480. package/lib/swipl/library/prolog_pack.pl +3906 -0
  481. package/lib/swipl/library/prolog_profile.pl +346 -0
  482. package/lib/swipl/library/prolog_qlfmake.pl +533 -0
  483. package/lib/swipl/library/prolog_source.pl +1188 -0
  484. package/lib/swipl/library/prolog_stack.pl +794 -0
  485. package/lib/swipl/library/prolog_trace.pl +365 -0
  486. package/lib/swipl/library/prolog_versions.pl +347 -0
  487. package/lib/swipl/library/prolog_wrap.pl +164 -0
  488. package/lib/swipl/library/prolog_xref.pl +3090 -0
  489. package/lib/swipl/library/prolog_xref.qlf +0 -0
  490. package/lib/swipl/library/pure_input.pl +266 -0
  491. package/lib/swipl/library/qpforeign.pl +695 -0
  492. package/lib/swipl/library/qsave.pl +1516 -0
  493. package/lib/swipl/library/quasi_quotations.pl +300 -0
  494. package/lib/swipl/library/quintus.pl +437 -0
  495. package/lib/swipl/library/random.pl +459 -0
  496. package/lib/swipl/library/rbtrees.pl +1153 -0
  497. package/lib/swipl/library/readln.pl +256 -0
  498. package/lib/swipl/library/readutil.pl +304 -0
  499. package/lib/swipl/library/record.pl +544 -0
  500. package/lib/swipl/library/rwlocks.pl +172 -0
  501. package/lib/swipl/library/sandbox.pl +1384 -0
  502. package/lib/swipl/library/semweb/dc.rdfs +198 -0
  503. package/lib/swipl/library/semweb/eor.rdfs +95 -0
  504. package/lib/swipl/library/semweb/owl.owl +287 -0
  505. package/lib/swipl/library/semweb/rdf_library.ttl +90 -0
  506. package/lib/swipl/library/semweb/rdfs.rdfs +251 -0
  507. package/lib/swipl/library/settings.pl +755 -0
  508. package/lib/swipl/library/shell.pl +462 -0
  509. package/lib/swipl/library/shlib.pl +670 -0
  510. package/lib/swipl/library/solution_sequences.pl +439 -0
  511. package/lib/swipl/library/sort.pl +119 -0
  512. package/lib/swipl/library/statistics.pl +541 -0
  513. package/lib/swipl/library/streams.pl +118 -0
  514. package/lib/swipl/library/strings.pl +469 -0
  515. package/lib/swipl/library/system.pl +95 -0
  516. package/lib/swipl/library/tables.pl +381 -0
  517. package/lib/swipl/library/tableutil.pl +771 -0
  518. package/lib/swipl/library/tabling.pl +42 -0
  519. package/lib/swipl/library/terms.pl +457 -0
  520. package/lib/swipl/library/theme/auto.pl +61 -0
  521. package/lib/swipl/library/theme/dark.pl +455 -0
  522. package/lib/swipl/library/theme/light.pl +45 -0
  523. package/lib/swipl/library/thread.pl +810 -0
  524. package/lib/swipl/library/thread_pool.pl +508 -0
  525. package/lib/swipl/library/threadutil.pl +574 -0
  526. package/lib/swipl/library/tty.pl +316 -0
  527. package/lib/swipl/library/ugraphs.pl +644 -0
  528. package/lib/swipl/library/unicode/INDEX.pl +6 -0
  529. package/lib/swipl/library/unicode/blocks.pl +414 -0
  530. package/lib/swipl/library/url.pl +1129 -0
  531. package/lib/swipl/library/utf8.pl +145 -0
  532. package/lib/swipl/library/varnumbers.pl +221 -0
  533. package/lib/swipl/library/vm.pl +251 -0
  534. package/lib/swipl/library/wfs.pl +205 -0
  535. package/lib/swipl/library/when.pl +263 -0
  536. package/lib/swipl/library/writef.pl +278 -0
  537. package/lib/swipl/library/www_browser.pl +251 -0
  538. package/lib/swipl/library/yall.pl +574 -0
  539. package/lib/swipl/library/zip.pl +211 -0
  540. package/lib/swipl/swipl.home +1 -0
  541. package/lib/vendor/libcrypto.so.3 +0 -0
  542. package/lib/vendor/libpcre2-8.so.0 +0 -0
  543. package/lib/vendor/libssl.so.3 +0 -0
  544. package/lib/vendor/libz.so.1 +0 -0
  545. package/licenses/OpenSSL-LICENSE.txt +177 -0
  546. package/licenses/PCRE2-COPYING +5 -0
  547. package/licenses/README.md +12 -0
  548. package/licenses/SWI-Prolog-LICENSE +41 -0
  549. package/licenses/zlib-LICENSE +22 -0
  550. package/package.json +27 -0
@@ -0,0 +1,600 @@
1
+ /* Part of SWI-Prolog
2
+
3
+ Author: Jan Wielemaker
4
+ E-mail: J.Wielemaker@vu.nl
5
+ WWW: http://www.swi-prolog.org
6
+ Copyright (c) 2014-2020, VU University Amsterdam
7
+ CWI Amsterdam
8
+ All rights reserved.
9
+
10
+ Redistribution and use in source and binary forms, with or without
11
+ modification, are permitted provided that the following conditions
12
+ are met:
13
+
14
+ 1. Redistributions of source code must retain the above copyright
15
+ notice, this list of conditions and the following disclaimer.
16
+
17
+ 2. Redistributions in binary form must reproduce the above copyright
18
+ notice, this list of conditions and the following disclaimer in
19
+ the documentation and/or other materials provided with the
20
+ distribution.
21
+
22
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
23
+ "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
24
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
25
+ FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
26
+ COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
27
+ INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
28
+ BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
29
+ LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
30
+ CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31
+ LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
32
+ ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
33
+ POSSIBILITY OF SUCH DAMAGE.
34
+ */
35
+
36
+ :- module(hub,
37
+ [ hub_create/3, % +HubName, -Hub, +Options
38
+ hub_add/3, % +HubName, +Websocket, ?Id
39
+ hub_member/2, % +HubName, ?Id
40
+ hub_send/2, % +ClientId, +Message
41
+ hub_broadcast/2, % +HubName, +Message
42
+ hub_broadcast/3, % +HubName, +Message, +Condition
43
+ current_hub/2 % ?HubName, ?Hub
44
+ ]).
45
+ :- use_module(library(debug)).
46
+ :- use_module(library(error)).
47
+ :- use_module(library(apply)).
48
+ :- use_module(library(gensym)).
49
+ :- if(exists_source(library(uuid))).
50
+ :- use_module(library(uuid)).
51
+ :- endif.
52
+ :- use_module(library(ordsets)).
53
+ :- use_module(library(http/websocket)).
54
+
55
+ :- meta_predicate
56
+ hub_broadcast(+,+,1).
57
+
58
+ /** <module> Manage a hub for websockets
59
+
60
+ This library manages a hub that consists of clients that are connected
61
+ using a websocket. Messages arriving at any of the websockets are sent
62
+ to the _event_ queue of the hub. In addition, the hub provides a
63
+ _broadcast_ interface. A typical usage scenario for a hub is a _chat
64
+ server_ A scenario for realizing an chat server is:
65
+
66
+ 1. Create a new hub using hub_create/3.
67
+ 2. Create one or more threads that listen to Hub.queues.event from
68
+ the created hub. These threads can update the shared view of the
69
+ world. A message is a dict as returned by ws_receive/2 or a
70
+ hub control message. Currently, the following control messages
71
+ are defined:
72
+
73
+ - hub{left:ClientId, reason:Reason, error:Error}
74
+ A client left us because of an I/O error. Reason is =read=
75
+ or =write= and Error is the Prolog I/O exception.
76
+
77
+ - hub{joined:ClientId}
78
+ A new client has joined the chatroom.
79
+
80
+ The thread(s) can talk to clients using two predicates:
81
+
82
+ - hub_send/2 sends a message to a specific client
83
+ - hub_broadcast/2 sends a message to all clients of the
84
+ hub.
85
+
86
+ A hub consists of (currently) four message queues and a simple dynamic
87
+ fact. Threads that are needed for the communication tasks are created on
88
+ demand and die if no more work needs to be done.
89
+
90
+ @tbd The current design does not use threads to perform tasks for
91
+ multiple hubs. This implies that the design scales rather
92
+ poorly for hosting many hubs with few users.
93
+ */
94
+
95
+ :- dynamic
96
+ hub/2, % Hub, Queues ...
97
+ websocket/5. % Hub, Socket, Queue, Lock, Id
98
+
99
+ :- volatile hub/2, websocket/5.
100
+
101
+ %! hub_create(+Name, -Hub, +Options) is det.
102
+ %
103
+ % Create a new hub. Hub is a dict containing the following public
104
+ % information:
105
+ %
106
+ % - Hub.name
107
+ % The name of the hub (the Name argument)
108
+ % - queues.event
109
+ % Message queue to which the hub thread(s) can listen.
110
+ %
111
+ % After creating a hub, the application normally creates a thread
112
+ % that listens to Hub.queues.event and exposes some mechanisms to
113
+ % establish websockets and add them to the hub using hub_add/3.
114
+ %
115
+ % @see http_upgrade_to_websocket/3 establishes a websocket from
116
+ % the SWI-Prolog webserver.
117
+
118
+ hub_create(HubName, Hub, _Options) :-
119
+ must_be(atom, HubName),
120
+ message_queue_create(WaitQueue),
121
+ message_queue_create(ReadyQueue),
122
+ message_queue_create(EventQueue),
123
+ message_queue_create(BroadcastQueue),
124
+ Hub = hub{name:HubName,
125
+ queues:_{wait:WaitQueue,
126
+ ready:ReadyQueue,
127
+ event:EventQueue,
128
+ broadcast:BroadcastQueue
129
+ }},
130
+ assertz(hub(HubName, Hub)).
131
+
132
+
133
+ %! current_hub(?Name, ?Hub) is nondet.
134
+ %
135
+ % True when there exists a hub Hub with Name.
136
+
137
+ current_hub(HubName, Hub) :-
138
+ hub(HubName, Hub).
139
+
140
+
141
+ /*******************************
142
+ * WAITERS *
143
+ *******************************/
144
+
145
+ /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
146
+ The task of this layer is to wait for (a potentially large number of)
147
+ websockets. Whenever there is data on one of these sockets, the socket
148
+ is handed to Hub.queues.ready. This is realised using wait_for_input/3,
149
+ which allows a single thread to wait for many sockets. But ... on
150
+ Windows it allows to wait for at most 64 sockets. In addition, there is
151
+ no way to add an additional input for control messages because Windows
152
+ select() can only wait for sockets. On Unix we could use pipe/2 to add
153
+ the control channel. On Windows we would need an additional network
154
+ service, giving rise its own problems with allocation, firewalls and
155
+ security.
156
+
157
+ So, instead we keep a queue of websockets that need to be waited for.
158
+ Whenever we add a websocket, we create a waiter thread that will
159
+ typically start waiting for this socket. In addition, we schedule any
160
+ waiting thread that has less than the maximum number of sockets to
161
+ timeout at as good as we can the same time. All of them will hunt for
162
+ the same set of queues, but they have to wait for each other and
163
+ therefore most of the time one thread will walk away with all websockets
164
+ and the others commit suicide because there is nothing to wait for.
165
+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
166
+
167
+ :- meta_predicate
168
+ hub_thread(0, +, +).
169
+
170
+ %! hub_add(+Hub, +WebSocket, ?Id) is det.
171
+ %
172
+ % Add a WebSocket to the hub. Id is used to identify this user. It may
173
+ % be provided (as a ground term) or is generated as a UUID.
174
+
175
+ hub_add(HubName, WebSocket, Id) :-
176
+ must_be(atom, HubName),
177
+ hub(HubName, Hub),
178
+ ( var(Id)
179
+ -> uuid(Id)
180
+ ; true
181
+ ),
182
+ message_queue_create(OutputQueue),
183
+ mutex_create(Lock),
184
+ % asserta/1 allows for reuse of Id
185
+ asserta(websocket(HubName, WebSocket, OutputQueue, Lock, Id)),
186
+ thread_send_message(Hub.queues.wait, WebSocket),
187
+ thread_send_message(Hub.queues.event,
188
+ hub{joined:Id}),
189
+ debug(hub(gate), 'Joined ~w: ~w', [HubName, Id]),
190
+ create_wait_thread(Hub).
191
+
192
+ %! hub_member(?HubName, ?Id) is nondet.
193
+ %
194
+ % True when Id is a member of the hub HubName.
195
+
196
+ hub_member(HubName, Id) :-
197
+ websocket(HubName, _WebSocket, _OutputQueue, _Lock, Id).
198
+
199
+ :- if(\+current_predicate(uuid/1)).
200
+ % FIXME: Proper pure Prolog random UUID implementation
201
+ uuid(UUID) :-
202
+ A is random(1<<63),
203
+ format(atom(UUID), '~d', [A]).
204
+ :- endif.
205
+
206
+ create_wait_thread(Hub) :-
207
+ hub_thread(wait_for_sockets(Hub), Hub, hub_wait_).
208
+
209
+ wait_for_sockets(Hub) :-
210
+ wait_for_sockets(Hub, 64).
211
+
212
+ wait_for_sockets(Hub, Max) :-
213
+ Queues = Hub.queues,
214
+ repeat,
215
+ get_messages(Queues.wait, Max, List),
216
+ ( List \== []
217
+ -> create_new_waiter_if_needed(Hub),
218
+ sort(List, Set),
219
+ ( debugging(hub(wait))
220
+ -> length(Set, Len),
221
+ debug(hub(wait), 'Waiting for ~d queues', [Len])
222
+ ; true
223
+ ),
224
+ wait_for_set(Set, Left, ReadySet, Max),
225
+ ( ReadySet \== []
226
+ -> debug(hub(ready), 'Data on ~p', [ReadySet]),
227
+ Ready = Queues.ready,
228
+ maplist(thread_send_message(Ready), ReadySet),
229
+ create_reader_threads(Hub),
230
+ ord_subtract(Set, ReadySet, NotReadySet)
231
+ ; NotReadySet = Left % timeout
232
+ ),
233
+ ( NotReadySet \== []
234
+ -> debug(hub(wait), 'Re-scheduling: ~p', [NotReadySet]),
235
+ Wait = Queues.wait,
236
+ maplist(thread_send_message(Wait), NotReadySet),
237
+ fail
238
+ ; true
239
+ )
240
+ ; !
241
+ ).
242
+
243
+ create_new_waiter_if_needed(Hub) :-
244
+ message_queue_property(Hub.queues.wait, size(0)),
245
+ !.
246
+ create_new_waiter_if_needed(Hub) :-
247
+ create_wait_thread(Hub).
248
+
249
+ %! wait_for_set(+Set0, -Left, -Ready, +Max) is det.
250
+ %
251
+ % Wait for input from Set0. Note that Set0 may contain closed
252
+ % websockets.
253
+
254
+ wait_for_set([], [], [], _) :-
255
+ !.
256
+ wait_for_set(Set0, Set, ReadySet, Max) :-
257
+ wait_timeout(Set0, Max, Timeout),
258
+ catch(wait_for_input(Set0, ReadySet, Timeout),
259
+ error(existence_error(stream, S), _), true),
260
+ ( var(S)
261
+ -> Set = Set0
262
+ ; delete(Set0, S, Set1),
263
+ wait_for_set(Set1, Set, ReadySet, Max)
264
+ ).
265
+
266
+
267
+ %! wait_timeout(+WaitForList, +Max, -TimeOut) is det.
268
+ %
269
+ % Determine the timeout, such that multiple threads waiting for
270
+ % less than the maximum number of sockets time out at the same
271
+ % moment and we can combine them on a single thread.
272
+
273
+ :- dynamic
274
+ scheduled_timeout/1.
275
+
276
+ wait_timeout(List, Max, Timeout) :-
277
+ length(List, Max),
278
+ !,
279
+ Timeout = infinite.
280
+ wait_timeout(_, _, Timeout) :-
281
+ get_time(Now),
282
+ ( scheduled_timeout(SchedAt)
283
+ -> ( SchedAt > Now
284
+ -> At = SchedAt
285
+ ; retractall(scheduled_timeout(_)),
286
+ At is ceiling(Now) + 1,
287
+ asserta(scheduled_timeout(At))
288
+ )
289
+ ; At is ceiling(Now) + 1,
290
+ asserta(scheduled_timeout(At))
291
+ ),
292
+ Timeout is At - Now.
293
+
294
+
295
+ %! get_messages(+Queue, +Max, -List) is det.
296
+ %
297
+ % Get the next Max messages from Queue or as many as there are
298
+ % available without blocking very long. This routine is designed
299
+ % such that if multiple threads are running for messages, one gets
300
+ % all of them and the others nothing.
301
+
302
+ get_messages(Q, N, List) :-
303
+ with_mutex(hub_wait,
304
+ get_messages_sync(Q, N, List)).
305
+
306
+ get_messages_sync(Q, N, [H|T]) :-
307
+ succ(N2, N),
308
+ thread_get_message(Q, H, [timeout(0.01)]),
309
+ !,
310
+ get_messages_sync(Q, N2, T).
311
+ get_messages_sync(_, _, []).
312
+
313
+
314
+ /*******************************
315
+ * READERS *
316
+ *******************************/
317
+
318
+ /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
319
+ The next layer consists of `readers'. Whenever one or more websockets
320
+ have data, the socket is added to Hub.queues.ready and
321
+ create_reader_threads/1 is called. This examines the number of ready
322
+ sockets and fires a number of threads to handle the read requests.
323
+ Multiple threads are mainly needed for the case that a client signals to
324
+ be ready, but only provides an incomplete message, causing the
325
+ ws_receive/2 to block.
326
+
327
+ Each of the threads reads the next message and sends this to
328
+ Hub.queues.event. The websocket is then rescheduled to listen for new
329
+ events. This read either fires a thread to listen for the new waiting
330
+ socket using create_wait_thread/1 or, if there are no more websockets,
331
+ does this job itself. This deals with the common scenario that one
332
+ client wakes up, starts a thread to read its event and waits for new
333
+ messages on the same websockets.
334
+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
335
+
336
+ create_reader_threads(Hub) :-
337
+ message_queue_property(Hub.queues.ready, size(Ready)),
338
+ Threads is ceiling(sqrt(Ready)),
339
+ forall(between(1, Threads, _),
340
+ create_reader_thread(Hub)).
341
+
342
+ create_reader_thread(Hub) :-
343
+ hub_thread(read_message(Hub), Hub, hub_read_ws_).
344
+
345
+ read_message(Hub) :-
346
+ Queues = Hub.queues,
347
+ thread_get_message(Queues.ready, WS, [timeout(0)]),
348
+ !,
349
+ catch(ws_receive(WS, Message), Error, true),
350
+ ( var(Error),
351
+ websocket(HubName, WS, _, _, Id)
352
+ -> ( Message.get(opcode) == close
353
+ -> close_client(WS, Message)
354
+ ; Event = Message.put(_{client:Id, hub:HubName}),
355
+ debug(hub(event), 'Event: ~p', [Event]),
356
+ thread_send_message(Queues.event, Event),
357
+ ( Message.get(opcode) == close
358
+ -> CloseError = error(_,_),
359
+ catch(ws_close(WS, 1000, ""), CloseError,
360
+ ws_warning(CloseError))
361
+ ; thread_send_message(Queues.wait, WS)
362
+ ),
363
+ ( message_queue_property(Queues.ready, size(0))
364
+ -> !,
365
+ wait_for_sockets(Hub)
366
+ ; create_wait_thread(Hub),
367
+ read_message(Hub)
368
+ )
369
+ )
370
+ ; websocket(_, WS, _, _, _)
371
+ -> io_read_error(WS, Error),
372
+ read_message(Hub)
373
+ ; read_message(Hub) % already destroyed
374
+ ).
375
+ read_message(_).
376
+
377
+ ws_warning(error(Formal, _)) :-
378
+ silent(Formal),
379
+ !.
380
+ ws_warning(Error) :-
381
+ print_message(warning, Error).
382
+
383
+ silent(socket_error(epipe, _)).
384
+
385
+ %! io_read_error(+WebSocket, +Error)
386
+ %
387
+ % Called on a read error from WebSocket. We close the websocket and
388
+ % send the hub an event that we lost the connection to the specified
389
+ % client. Note that we leave destruction of the anonymous message
390
+ % queue and mutex to the Prolog garbage collector.
391
+
392
+ io_read_error(WebSocket, Error) :-
393
+ debug(hub(gate), 'Got read error on ~w: ~p',
394
+ [WebSocket, Error]),
395
+ retract(websocket(HubName, WebSocket, _Queue, _Lock, Id)),
396
+ !,
397
+ E = error(_,_),
398
+ catch(ws_close(WebSocket, 1011, Error), E,
399
+ ws_warning(E)),
400
+ hub(HubName, Hub),
401
+ thread_send_message(Hub.queues.event,
402
+ hub{left:Id,
403
+ hub:HubName,
404
+ reason:read,
405
+ error:Error}).
406
+ io_read_error(_, _). % already considered gone
407
+
408
+ close_client(WebSocket, Message) :-
409
+ Message.get(data) == end_of_file,
410
+ !,
411
+ io_read_error(WebSocket, end_of_file).
412
+ close_client(WebSocket, Message) :-
413
+ retract(websocket(HubName, WebSocket, _Queue, _Lock, Id)),
414
+ !,
415
+ E = error(_,_),
416
+ catch(ws_close(WebSocket, 1000, "Bye"), E,
417
+ ws_warning(E)),
418
+ hub(HubName, Hub),
419
+ thread_send_message(Hub.queues.event,
420
+ hub{left:Id,
421
+ hub:HubName,
422
+ reason:close,
423
+ data:Message.data
424
+ }).
425
+
426
+ %! io_write_error(+WebSocket, +Message, +Error)
427
+ %
428
+ % Failed to write Message to WebSocket due to Error. Note that this
429
+ % may be a pending but closed WebSocket. We first check whether there
430
+ % is a new one and if not send a `left` message and pass the error
431
+ % such that the client can re-send it when appropriate.
432
+
433
+ io_write_error(WebSocket, Message, Error) :-
434
+ debug(hub(gate), 'Got write error on ~w: ~p',
435
+ [WebSocket, Error]),
436
+ retract(websocket(HubName, WebSocket, _Queue, _Lock, Id)),
437
+ !,
438
+ catch(ws_close(WebSocket, 1011, Error), _, true),
439
+ ( websocket(_, _, _, _, Id)
440
+ -> true
441
+ ; hub(HubName, Hub),
442
+ thread_send_message(Hub.queues.event,
443
+ hub{left:Id,
444
+ hub:HubName,
445
+ reason:write(Message),
446
+ error:Error})
447
+ ).
448
+ io_write_error(_, _, _). % already considered gone
449
+
450
+
451
+ /*******************************
452
+ * SENDING MESSAGES *
453
+ *******************************/
454
+
455
+ /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
456
+ My initial thought about sending messages was to add a tuple
457
+ WebSocket-Message to an output queue and have a dynamic number of
458
+ threads sending these messages to the websockets. But, it is desirable
459
+ that, if multiple messages are sent to a particular client, they arrive
460
+ in this order. As multiple threads are performing this task, this is not
461
+ easy to guarantee. Therefore, we create an output queue and a mutex for
462
+ each client. An output thread will walk along the websockets, looking
463
+ for one that has pending messages. It then grabs the lock associated
464
+ with the client and sends all waiting output messages.
465
+
466
+ The price is that we might peek a significant number of message queues
467
+ before we find one that contains messages. If this proves to be a
468
+ significant problem, we could maintain a queue of queues holding
469
+ messages.
470
+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
471
+
472
+ %! hub_send(+ClientId, +Message) is semidet.
473
+ %
474
+ % Send message to the indicated ClientId. Fails silently if ClientId
475
+ % does not exist.
476
+ %
477
+ % @arg Message is either a single message (as accepted by
478
+ % ws_send/2) or a list of such messages.
479
+
480
+ hub_send(ClientId, Message) :-
481
+ websocket(HubName, _WS, ClientQueue, _Lock, ClientId),
482
+ hub(HubName, Hub),
483
+ ( is_list(Message)
484
+ -> maplist(queue_output(ClientQueue), Message)
485
+ ; queue_output(ClientQueue, Message)
486
+ ),
487
+ create_output_thread(Hub, ClientQueue).
488
+
489
+ create_output_thread(Hub, Queue) :-
490
+ hub_thread(broadcast_from_queue(Queue, [timeout(0)]),
491
+ Hub, hub_out_q_).
492
+
493
+ %! hub_broadcast(+Hub, +Message) is det.
494
+ %! hub_broadcast(+Hub, +Message, :Condition) is det.
495
+ %
496
+ % Send Message to all websockets associated with Hub for which
497
+ % call(Condition, Id) succeeds. Note that this process is
498
+ % _asynchronous_: this predicate returns immediately after putting
499
+ % all requests in a broadcast queue. If a message cannot be
500
+ % delivered due to a network error, the hub is informed through
501
+ % io_error/3.
502
+
503
+ hub_broadcast(HubName, Message) :-
504
+ hub_broadcast(HubName, Message, all).
505
+
506
+ all(_).
507
+
508
+ hub_broadcast(HubName, Message, Condition) :-
509
+ must_be(atom, HubName),
510
+ hub(HubName, Hub),
511
+ State = count(0),
512
+ forall(( websocket(HubName, _WS, ClientQueue, _Lock, Id),
513
+ call(Condition, Id)
514
+ ),
515
+ ( queue_output(ClientQueue, Message),
516
+ inc_count(State)
517
+ )),
518
+ State = count(Count),
519
+ create_broadcast_threads(Hub, Count).
520
+
521
+ queue_output(Queue, Message) :-
522
+ thread_send_message(Queue, Message).
523
+
524
+ inc_count(State) :-
525
+ arg(1, State, C0),
526
+ C1 is C0+1,
527
+ nb_setarg(1, State, C1).
528
+
529
+ create_broadcast_threads(Hub, Count) :-
530
+ Threads is ceiling(sqrt(Count)),
531
+ forall(between(1, Threads, _),
532
+ create_broadcast_thread(Hub)).
533
+
534
+ create_broadcast_thread(Hub) :-
535
+ current_prolog_flag(threads, true),
536
+ !,
537
+ hub_thread(broadcast_from_queues(Hub, [timeout(0)]),
538
+ Hub, hub_out_all_).
539
+ create_broadcast_thread(_). % we are shutting down
540
+
541
+ %! broadcast_from_queues(+Hub, +Options) is det.
542
+ %
543
+ % Broadcast from over all known queues.
544
+
545
+ broadcast_from_queues(Hub, Options) :-
546
+ forall(websocket(Hub.name, _WebSocket, Queue, _Lock, _Id),
547
+ broadcast_from_queue(Queue, Options)).
548
+
549
+
550
+ %! broadcast_from_queue(+Queue, +Options) is det.
551
+ %
552
+ % Send all messages pending for Queue. Note that this predicate
553
+ % locks the mutex associated with the Queue, such that other
554
+ % workers cannot start sending messages to this client. Concurrent
555
+ % sending would lead to out-of-order arrival of broadcast
556
+ % messages. If the mutex is already held, someone else is
557
+ % processing this message queue, so we don't have to worry.
558
+
559
+ broadcast_from_queue(Queue, _Options) :-
560
+ message_queue_property(Queue, size(0)),
561
+ !.
562
+ broadcast_from_queue(Queue, Options) :-
563
+ websocket(_Hub, _WebSocket, Queue, Lock, _Id),
564
+ !,
565
+ ( setup_call_cleanup(
566
+ mutex_trylock(Lock),
567
+ broadcast_from_queue_sync(Queue, Options),
568
+ mutex_unlock(Lock))
569
+ -> true
570
+ ; true
571
+ ).
572
+ broadcast_from_queue(_, _).
573
+
574
+ % Note that we re-fetch websocket/5, such that we terminate if something
575
+ % closed the websocket.
576
+
577
+ broadcast_from_queue_sync(Queue, Options) :-
578
+ repeat,
579
+ ( websocket(_Hub, WebSocket, Queue, _Lock, _Id),
580
+ thread_get_message(Queue, Message, Options)
581
+ -> debug(hub(broadcast),
582
+ 'To: ~p messages: ~p', [WebSocket, Message]),
583
+ catch(ws_send(WebSocket, Message), E,
584
+ io_write_error(WebSocket, Message, E)),
585
+ fail
586
+ ; !
587
+ ).
588
+
589
+ %! hub_thread(:Goal, +Hub, +Task) is det.
590
+ %
591
+ % Create a (temporary) thread for the hub to perform Task. We
592
+ % created named threads if debugging hub(thread) is enabled.
593
+
594
+ hub_thread(Goal, _, Task) :-
595
+ debugging(hub(thread)),
596
+ !,
597
+ gensym(Task, Alias),
598
+ thread_create(Goal, _, [detached(true), alias(Alias)]).
599
+ hub_thread(Goal, _, _) :-
600
+ thread_create(Goal, _, [detached(true)]).