# Universal Doclets Architecture Overview Universal Doclets is a vision on how to achieve re-usable data and code over the current web. Building a new world-wide infrastructure might yield a more optimized experience, but the likelyhood of getting any kind of market share is low. ## Aims: - make it possible to create applications by re-using existing and untrusted components, over the network. - make it simple enough that unsophisticated developers can create their own applications - make it live, no dead code, no API's - make it collaborative - applications should be able to run anywhere ## Doclets A doclet is a webpage that contains code, view and data in one. It must also be able to communicate with other doclets, even, or especially untrusted doclets, served from different domains. A simple doclet is first and foremost a html document. But it might only have enough html to start its main javascript code block, e.g: ```htmlembedded= <!doctype html> <meta charset="utf8"> <script src="main.js"></script> <!-- remaining content in whatever format to be handled by main.js ``` A doclet has a URL where it is hosted. You can embed a doclet by adding an iframe, e.g.: ```htmlembedded= <!doctype html> <meta charset="utf8"> <body> <h1>My own doclet</h1> <iframe src="https://www.example.com/another-doclet.html"> </iframe> <script src="mydoclet.js"></script> </body> ``` ## Cross Iframe Communication Embedded cross-domain doclets contain untrusted code. So you cannot access the contents of a cross-domain iframe directly. The only communication method available is the postMessage api. Each Window in the browser, including iframes, allow you to send a messageEvent to it, through the postMessage() function. In the target Window, you must listen for the messageEvent to parse its contents and respond. So only HTML pages that opt-in to this system will be able to participate. The postMessage API is already used for this exact purpose, e.g. here: - [Krakenjs/post-robot](https://github.com/krakenjs/post-robot/) In fact, [Krakenjs/zoid](https://github.com/krakenjs/zoid) is very similar to the doclet idea. ## Collaboration between doclets Once communication is established between two doclets, there needs to be a way to match capabilities. The aim is not to make this automatic, though in the future this may become possible. However the focus is now on allowing a user to link two doclets by interrogating the capabilities of the doclets and linking them up. The inspiration here are Hypercard and SmallTalk. Each doclet should have an introspection API that allows a development UI to show the options/capabilities of each doclet. The danger here is that we simply get a different version of API programming. API's, as currently in use on the web, are too limited. Each API is a unique code contract, which requires a lot of bespoke programming to make use of it. In addition, the code does not run in the same space as the data. So it is extremely limited in capability compared to code that does have full access to the data. Compare code running on a client that talks to a large database. It needs to query the database for a subset of the data, transfer that and convert it to something useful. Instead the client could send code to the database server, where it would have full access to all code and send over the result. Graphql is a step in this direction, compared to the defaul 'REST' API's. A more comprehensive approach can be found in [CouchDB](https://couchapp.readthedocs.io/en/latest/intro/what-is-couchapp.html). Here you can send programs written in javascript to the server to be run there, and send results back. Another good example is the [Pengine system in SWI-Prolog](https://pengines.swi-prolog.org/docs/index.html). ## Data Comprehension When linking doclets together, we still have the problem of understanding the data. Each program today has its own data models and code that uses those. You cannot simply grab the data from one program and re-use it in another. Because the linking of two doclets is a manual step, we can pass this problem on to the end suer, but that means that linking two doclets becomes non-trivial. Instead there should be a capabilities negotiation protocol, whereby two doclets can check if they have compatible API's and datamodels. Then the user only has to select one or more of the matches. In addition, the user may also use a library of predefined conversion code that allows him/her to link up two incompatible API's through a bridge library. To do this, we need globally unique identifiers for each API. The logical starting point is to use URI's for this, since doclets already run on a URL. However, we should also support more general identifiers, so that multiple doclets could implement the same API or capability. So URN's should also be supported.