issue_comments
25 rows where author_association = "OWNER", issue_url = "https://api.github.com/repos/simonw/datasette/issues/983" and "updated_at" is on date 2020-12-30
This data as json, CSV (advanced)
Suggested facets: created_at (date)
id ▼ | html_url | issue_url | node_id | user | created_at | updated_at | author_association | body | reactions | issue | performed_via_github_app |
---|---|---|---|---|---|---|---|---|---|---|---|
752715236 | https://github.com/simonw/datasette/issues/983#issuecomment-752715236 | https://api.github.com/repos/simonw/datasette/issues/983 | MDEyOklzc3VlQ29tbWVudDc1MjcxNTIzNg== | simonw 9599 | 2020-12-30T18:24:54Z | 2020-12-30T18:24:54Z | OWNER | I think I'm going to try building a very lightweight clone of the core API design of Pluggy - not the advanced features, just the idea that plugins can register and a call to `plugin.nameOfHook()` will return the concatenated results of all of the registered hooks. | {"total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0} | JavaScript plugin hooks mechanism similar to pluggy 712260429 | |
752715412 | https://github.com/simonw/datasette/issues/983#issuecomment-752715412 | https://api.github.com/repos/simonw/datasette/issues/983 | MDEyOklzc3VlQ29tbWVudDc1MjcxNTQxMg== | simonw 9599 | 2020-12-30T18:25:31Z | 2020-12-30T18:25:31Z | OWNER | I'm going to introduce a global `datasette` object which holds all the documented JavaScript API for plugin authors. | {"total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0} | JavaScript plugin hooks mechanism similar to pluggy 712260429 | |
752721069 | https://github.com/simonw/datasette/issues/983#issuecomment-752721069 | https://api.github.com/repos/simonw/datasette/issues/983 | MDEyOklzc3VlQ29tbWVudDc1MjcyMTA2OQ== | simonw 9599 | 2020-12-30T18:46:10Z | 2020-12-30T18:46:10Z | OWNER | Pluggy does dependency injection by introspecting the named arguments to the Python function, which I really like. That's tricker in JavaScript. It looks like the only way to introspect a function is to look at the `.toString()` representation of it and parse the `(parameter, list)` using a regular expression. Even more challenging: JavaScript developers love minifying their code, and minification can shorten the function parameter names. From https://code-maven.com/dependency-injection-in-angularjs it looks like Angular.js does dependency injection and solves this by letting you optionally provide a separate list of the arguments your function uses: ```javascript angular.module('DemoApp', []) .controller('DemoController', ['$scope', '$log', function($scope, $log) { $scope.message = "Hello World"; $log.debug('logging hello'); }]); ``` I can copy that approach: I'll introspect by default, but provide a documented mechanism for explicitly listing your parameter names so that if you know your plugin code will be minified you can use that instead. | {"total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0} | JavaScript plugin hooks mechanism similar to pluggy 712260429 | |
752721840 | https://github.com/simonw/datasette/issues/983#issuecomment-752721840 | https://api.github.com/repos/simonw/datasette/issues/983 | MDEyOklzc3VlQ29tbWVudDc1MjcyMTg0MA== | simonw 9599 | 2020-12-30T18:48:53Z | 2020-12-30T18:51:51Z | OWNER | Potential design: ```javascript datasette.plugins.register('column_actions', function(database, table, column, actor) { /* ... *l }) ``` Or if you want to be explicit to survive minification: ```javascript datasette.plugins.register('column_actions', function(database, table, column, actor) { /* ... *l }, ['database', 'table', 'column', 'actor']) ``` I'm making that list of parameter names an optional third argument to the `register()` function. If that argument isn't passed, introspection will be used to figure out the parameter names. | {"total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0} | JavaScript plugin hooks mechanism similar to pluggy 712260429 | |
752722863 | https://github.com/simonw/datasette/issues/983#issuecomment-752722863 | https://api.github.com/repos/simonw/datasette/issues/983 | MDEyOklzc3VlQ29tbWVudDc1MjcyMjg2Mw== | simonw 9599 | 2020-12-30T18:52:39Z | 2020-12-30T18:52:39Z | OWNER | Then to call the plugins: ```javascript datasette.plugins.call('column_actions', {database: 'database', table: 'table'}) ``` | {"total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0} | JavaScript plugin hooks mechanism similar to pluggy 712260429 | |
752729035 | https://github.com/simonw/datasette/issues/983#issuecomment-752729035 | https://api.github.com/repos/simonw/datasette/issues/983 | MDEyOklzc3VlQ29tbWVudDc1MjcyOTAzNQ== | simonw 9599 | 2020-12-30T19:15:56Z | 2020-12-30T19:16:44Z | OWNER | The `column_actions` hook is the obvious first place to try this out. What are some demo plugins I could build for it? - Word cloud for this column - Count values (essentially linking to the SQL query for that column, as an extended version of the facet counts) - would be great if this could include pagination somehow, via #856. - Extract this column into a separate table - Add an index to this column | {"total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0} | JavaScript plugin hooks mechanism similar to pluggy 712260429 | |
752742669 | https://github.com/simonw/datasette/issues/983#issuecomment-752742669 | https://api.github.com/repos/simonw/datasette/issues/983 | MDEyOklzc3VlQ29tbWVudDc1Mjc0MjY2OQ== | simonw 9599 | 2020-12-30T20:07:05Z | 2020-12-30T20:07:18Z | OWNER | Initial prototype: ```javascript window.datasette = {}; window.datasette.plugins = (function() { var registry = {}; function extractParameters(fn) { var match = /\((.*)\)/.exec(fn.toString()); if (match && match[1].trim()) { return match[1].split(',').map(s => s.trim()); } else { return []; } } function register(hook, fn, parameters) { parameters = parameters || extractParameters(fn); if (!registry[hook]) { registry[hook] = []; } registry[hook].push([fn, parameters]); } function call(hook, args) { args = args || {}; var implementations = registry[hook] || []; var results = []; implementations.forEach(([fn, parameters]) => { /* Call with the correct arguments */ var callWith = parameters.map(parameter => args[parameter]); var result = fn.apply(fn, callWith); if (result) { results.push(result); } }); return results; } return { register: register, _registry: registry, call: call }; })(); ``` Usage example: ```javascript datasette.plugins.register('numbers', (a, b) => a + b) datasette.plugins.register('numbers', (a, b) => a * b) datasette.plugins.call('numbers', {a: 4, b: 6}) /* Returns [10, 24] */ ``` | {"total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0} | JavaScript plugin hooks mechanism similar to pluggy 712260429 | |
752744195 | https://github.com/simonw/datasette/issues/983#issuecomment-752744195 | https://api.github.com/repos/simonw/datasette/issues/983 | MDEyOklzc3VlQ29tbWVudDc1Mjc0NDE5NQ== | simonw 9599 | 2020-12-30T20:12:26Z | 2020-12-30T20:12:26Z | OWNER | This implementation doesn't have an equivalent of "hookspecs" which can identify if a registered plugin implementation matches a known signature. I should add that, it will provide a better developer experience if someone has a typo. | {"total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0} | JavaScript plugin hooks mechanism similar to pluggy 712260429 | |
752744311 | https://github.com/simonw/datasette/issues/983#issuecomment-752744311 | https://api.github.com/repos/simonw/datasette/issues/983 | MDEyOklzc3VlQ29tbWVudDc1Mjc0NDMxMQ== | simonw 9599 | 2020-12-30T20:12:50Z | 2020-12-30T20:13:02Z | OWNER | This could work to define a plugin hook: ```javascript datasette.plugins.define('numbers', ['a' ,'b']) ``` | {"total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0} | JavaScript plugin hooks mechanism similar to pluggy 712260429 | |
752747169 | https://github.com/simonw/datasette/issues/983#issuecomment-752747169 | https://api.github.com/repos/simonw/datasette/issues/983 | MDEyOklzc3VlQ29tbWVudDc1Mjc0NzE2OQ== | simonw 9599 | 2020-12-30T20:24:07Z | 2020-12-30T20:24:07Z | OWNER | This version adds `datasette.plugins.define()` plus extra validation of both `.register()` and `.call()`: ```javascript window.datasette = {}; window.datasette.plugins = (function() { var registry = {}; var definitions = {}; function extractParameters(fn) { var match = /\((.*)\)/.exec(fn.toString()); if (match && match[1].trim()) { return match[1].split(',').map(s => s.trim()); } else { return []; } } function define(hook, parameters) { definitions[hook] = parameters || []; } function isSubSet(a, b) { return a.every(parameter => b.includes(parameter)) } function register(hook, fn, parameters) { parameters = parameters || extractParameters(fn); if (!definitions[hook]) { throw new Error('"' + hook + '" is not a defined plugin hook'); } if (!definitions[hook]) { throw new Error('"' + hook + '" is not a defined plugin hook'); } /* Check parameters is a subset of definitions[hook] */ var validParameters = definitions[hook]; if (!isSubSet(parameters, validParameters)) { throw new Error('"' + hook + '" valid parameters are ' + JSON.stringify(validParameters)); } if (!registry[hook]) { registry[hook] = []; } registry[hook].push([fn, parameters]); } function call(hook, args) { args = args || {}; if (!definitions[hook]) { throw new Error('"' + hook + '" hook has not been defined'); } if (!isSubSet(Object.keys(args), definitions[hook])) { throw new Error('"' + hook + '" valid arguments are ' + JSON.stringify(definitions[hook])); } var implementations = registry[hook] || []; var results = []; implementations.forEach(([fn, parameters]) => { /* Call with the correct arguments */ var callWith =… | {"total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0} | JavaScript plugin hooks mechanism similar to pluggy 712260429 | |
752747999 | https://github.com/simonw/datasette/issues/983#issuecomment-752747999 | https://api.github.com/repos/simonw/datasette/issues/983 | MDEyOklzc3VlQ29tbWVudDc1Mjc0Nzk5OQ== | simonw 9599 | 2020-12-30T20:27:00Z | 2020-12-30T20:27:00Z | OWNER | I need to decide how this code is going to be loaded. Putting it in a blocking `<script>` element in the head would work, but I'd rather not block loading of the rest of the page. Using a `<script async>` method would be nicer, but then I have to worry about plugins attempting to register themselves before the page has fully loaded. Running it through https://javascript-minifier.com/ produces this, which is 855 characters - so maybe I could inline that into the header of the page? `window.datasette={},window.datasette.plugins=function(){var r={},n={};function e(r,n){return r.every(r=>n.includes(r))}return{define:function(r,e){n[r]=e||[]},register:function(t,i,o){if(o=o||function(r){var n=/\((.*)\)/.exec(r.toString());return n&&n[1].trim()?n[1].split(",").map(r=>r.trim()):[]}(i),!n[t])throw new Error('"'+t+'" is not a defined plugin hook');if(!n[t])throw new Error('"'+t+'" is not a defined plugin hook');var a=n[t];if(!e(o,a))throw new Error('"'+t+'" valid parameters are '+JSON.stringify(a));r[t]||(r[t]=[]),r[t].push([i,o])},_registry:r,call:function(t,i){if(i=i||{},!n[t])throw new Error('"'+t+'" hook has not been defined');if(!e(Object.keys(i),n[t]))throw new Error('"'+t+'" valid arguments are '+JSON.stringify(n[t]));var o=r[t]||[],a=[];return o.forEach(([r,n])=>{var e=n.map(r=>i[r]),t=r.apply(r,e);t&&a.push(t)}),a}}}();` | {"total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0} | JavaScript plugin hooks mechanism similar to pluggy 712260429 | |
752748496 | https://github.com/simonw/datasette/issues/983#issuecomment-752748496 | https://api.github.com/repos/simonw/datasette/issues/983 | MDEyOklzc3VlQ29tbWVudDc1Mjc0ODQ5Ng== | simonw 9599 | 2020-12-30T20:28:48Z | 2020-12-30T20:28:48Z | OWNER | If I'm going to minify it I'll need to figure out a build step in Datasette itself so that I can easily work on that minified version. | {"total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0} | JavaScript plugin hooks mechanism similar to pluggy 712260429 | |
752749189 | https://github.com/simonw/datasette/issues/983#issuecomment-752749189 | https://api.github.com/repos/simonw/datasette/issues/983 | MDEyOklzc3VlQ29tbWVudDc1Mjc0OTE4OQ== | simonw 9599 | 2020-12-30T20:31:28Z | 2020-12-30T20:31:28Z | OWNER | Using raw string exceptions, `throw '"' + hook + '" hook has not been defined';`, knocks it down to 795 characters. | {"total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0} | JavaScript plugin hooks mechanism similar to pluggy 712260429 | |
752750551 | https://github.com/simonw/datasette/issues/983#issuecomment-752750551 | https://api.github.com/repos/simonw/datasette/issues/983 | MDEyOklzc3VlQ29tbWVudDc1Mjc1MDU1MQ== | simonw 9599 | 2020-12-30T20:36:38Z | 2020-12-30T20:37:48Z | OWNER | This version minifies to 702 characters: ```javascript window.datasette = window.datasette || {}; window.datasette.plugins = (() => { var registry = {}; var definitions = {}; var stringify = JSON.stringify; function extractParameters(fn) { var match = /\((.*)\)/.exec(fn.toString()); if (match && match[1].trim()) { return match[1].split(',').map(s => s.trim()); } else { return []; } } function isSubSet(a, b) { return a.every(parameter => b.includes(parameter)) } return { _registry: registry, define: (hook, parameters) => { definitions[hook] = parameters || []; }, register: (hook, fn, parameters) => { parameters = parameters || extractParameters(fn); if (!definitions[hook]) { throw '"' + hook + '" is not a defined hook'; } /* Check parameters is a subset of definitions[hook] */ var validParameters = definitions[hook]; if (!isSubSet(parameters, validParameters)) { throw '"' + hook + '" valid args are ' + stringify(validParameters); } if (!registry[hook]) { registry[hook] = []; } registry[hook].push([fn, parameters]); }, call: (hook, args) => { args = args || {}; if (!definitions[hook]) { throw '"' + hook + '" hook is not defined'; } if (!isSubSet(Object.keys(args), definitions[hook])) { throw '"' + hook + '" valid args: ' + stringify(definitions[hook]); } var implementations = registry[hook] || []; var results = []; implementations.forEach(([fn, parameters]) => { /* Call with the correct arguments */ var callWith = parameters.map(parameter => args[parameter]); … | {"total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0} | JavaScript plugin hooks mechanism similar to pluggy 712260429 | |
752751490 | https://github.com/simonw/datasette/issues/983#issuecomment-752751490 | https://api.github.com/repos/simonw/datasette/issues/983 | MDEyOklzc3VlQ29tbWVudDc1Mjc1MTQ5MA== | simonw 9599 | 2020-12-30T20:40:04Z | 2020-12-30T21:34:22Z | OWNER | This one is 683 bytes with Uglify - I like how https://skalman.github.io/UglifyJS-online/ shows you the minified character count as you edit the script: ```javascript window.datasette = window.datasette || {}; window.datasette.plugins = (() => { var registry = {}; var definitions = {}; var stringify = JSON.stringify; function extractParameters(fn) { var match = /\((.*)\)/.exec(fn.toString()); if (match && match[1].trim()) { return match[1].split(',').map(s => s.trim()); } else { return []; } } function isSubSet(a, b) { return a.every(parameter => b.includes(parameter)) } return { _r: registry, define: (hook, parameters) => { definitions[hook] = parameters || []; }, register: (hook, fn, parameters) => { parameters = parameters || extractParameters(fn); if (!definitions[hook]) { throw 'Hook "' + hook + '" not defined'; } /* Check parameters is a subset of definitions[hook] */ var validParameters = definitions[hook]; if (!isSubSet(parameters, validParameters)) { throw '"' + hook + '" valid args: ' + stringify(validParameters); } if (!registry[hook]) { registry[hook] = []; } registry[hook].push([fn, parameters]); }, call: (hook, args) => { args = args || {}; if (!definitions[hook]) { throw '"' + hook + '" hook not defined'; } if (!isSubSet(Object.keys(args), definitions[hook])) { throw '"' + hook + '" valid args: ' + stringify(definitions[hook]); } var implementations = registry[hook] || []; var results = []; implementations.forEach(([fn, parameters]) => { /* Call with the correct… | {"total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0} | JavaScript plugin hooks mechanism similar to pluggy 712260429 | |
752757289 | https://github.com/simonw/datasette/issues/983#issuecomment-752757289 | https://api.github.com/repos/simonw/datasette/issues/983 | MDEyOklzc3VlQ29tbWVudDc1Mjc1NzI4OQ== | simonw 9599 | 2020-12-30T21:02:20Z | 2020-12-30T21:02:20Z | OWNER | I'm going to need to add JavaScript unit tests for this new plugin system. | {"total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0} | JavaScript plugin hooks mechanism similar to pluggy 712260429 | |
752758802 | https://github.com/simonw/datasette/issues/983#issuecomment-752758802 | https://api.github.com/repos/simonw/datasette/issues/983 | MDEyOklzc3VlQ29tbWVudDc1Mjc1ODgwMg== | simonw 9599 | 2020-12-30T21:07:33Z | 2020-12-30T21:10:10Z | OWNER | Removing the `datasette.plugin.define()` method and associated error handling reduces the uglified version from 683 bytes to 380 bytes. I think the error checking is worth the extra 303 bytes per page load, even if it's only really needed for a better developer experience. ```javascript window.datasette = window.datasette || {}; window.datasette.plugins = (() => { var registry = {}; function extractParameters(fn) { var match = /\((.*)\)/.exec(fn.toString()); if (match && match[1].trim()) { return match[1].split(',').map(s => s.trim()); } else { return []; } } return { register: (hook, fn, parameters) => { parameters = parameters || extractParameters(fn); if (!registry[hook]) { registry[hook] = []; } registry[hook].push([fn, parameters]); }, call: (hook, args) => { args = args || {}; var implementations = registry[hook] || []; var results = []; implementations.forEach(([fn, parameters]) => { /* Call with the correct arguments */ var callWith = parameters.map(parameter => args[parameter]); var result = fn.apply(fn, callWith); if (result) { results.push(result); } }); return results; } }; })(); ``` `window.datasette=window.datasette||{},window.datasette.plugins=(()=>{var t={};return{register:(r,a,e)=>{e=e||function(t){var r=/\((.*)\)/.exec(t.toString());return r&&r[1].trim()?r[1].split(",").map(t=>t.trim()):[]}(a),t[r]||(t[r]=[]),t[r].push([a,e])},call:(r,a)=>{a=a||{};var e=t[r]||[],i=[];return e.forEach(([t,r])=>{var e=r.map(t=>a[t]),n=t.apply(t,e);n&&i.push(n)}),i}}})();` | {"total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0} | JavaScript plugin hooks mechanism similar to pluggy 712260429 | |
752759885 | https://github.com/simonw/datasette/issues/983#issuecomment-752759885 | https://api.github.com/repos/simonw/datasette/issues/983 | MDEyOklzc3VlQ29tbWVudDc1Mjc1OTg4NQ== | simonw 9599 | 2020-12-30T21:11:52Z | 2020-12-30T21:14:00Z | OWNER | 262 bytes if I remove the parameter introspection code, instead requiring plugin authors to specify the arguments they take: ```javascript window.datasette = window.datasette || {}; window.datasette.plugins = (() => { var registry = {}; return { register: (hook, fn, parameters) => { if (!registry[hook]) { registry[hook] = []; } registry[hook].push([fn, parameters]); }, call: (hook, args) => { args = args || {}; var results = []; (registry[hook] || []).forEach(([fn, parameters]) => { /* Call with the correct arguments */ var callWith = parameters.map(parameter => args[parameter]); var result = fn.apply(fn, callWith); if (result) { results.push(result); } }); return results; } }; })(); ``` `window.datasette=window.datasette||{},window.datasette.plugins=(()=>{var a={};return{register:(t,e,r)=>{a[t]||(a[t]=[]),a[t].push([e,r])},call:(t,e)=>{e=e||{};var r=[];return(a[t]||[]).forEach(([a,t])=>{var s=t.map(a=>e[a]),d=a.apply(a,s);d&&r.push(d)}),r}}})();` | {"total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0} | JavaScript plugin hooks mechanism similar to pluggy 712260429 | |
752760054 | https://github.com/simonw/datasette/issues/983#issuecomment-752760054 | https://api.github.com/repos/simonw/datasette/issues/983 | MDEyOklzc3VlQ29tbWVudDc1Mjc2MDA1NA== | simonw 9599 | 2020-12-30T21:12:36Z | 2020-12-30T21:14:05Z | OWNER | I gotta admit that 262 byte version is pretty tempting, if it's going to end up in the `<head>` of every single page. | {"total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0} | JavaScript plugin hooks mechanism similar to pluggy 712260429 | |
752760815 | https://github.com/simonw/datasette/issues/983#issuecomment-752760815 | https://api.github.com/repos/simonw/datasette/issues/983 | MDEyOklzc3VlQ29tbWVudDc1Mjc2MDgxNQ== | simonw 9599 | 2020-12-30T21:15:41Z | 2020-12-30T21:15:41Z | OWNER | I'm going to write a few example plugins and try them out against the longer and shorter versions of the script, to get a better feel for how useful the longer versions with the error handling and explicit definition actually are. | {"total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0} | JavaScript plugin hooks mechanism similar to pluggy 712260429 | |
752767174 | https://github.com/simonw/datasette/issues/983#issuecomment-752767174 | https://api.github.com/repos/simonw/datasette/issues/983 | MDEyOklzc3VlQ29tbWVudDc1Mjc2NzE3NA== | simonw 9599 | 2020-12-30T21:40:44Z | 2020-12-30T21:40:44Z | OWNER | Started a Twitter thread about this here: https://twitter.com/simonw/status/1344392603794477056 | {"total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0} | JavaScript plugin hooks mechanism similar to pluggy 712260429 | |
752767500 | https://github.com/simonw/datasette/issues/983#issuecomment-752767500 | https://api.github.com/repos/simonw/datasette/issues/983 | MDEyOklzc3VlQ29tbWVudDc1Mjc2NzUwMA== | simonw 9599 | 2020-12-30T21:42:07Z | 2020-12-30T21:42:07Z | OWNER | Another option: have both "dev" and "production" versions of the plugin mechanism script. Make it easy to switch between the two. Build JavaScript unit tests that exercise the "production" APIs against the development version, and have extra tests that just work against the features in the development version. | {"total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0} | JavaScript plugin hooks mechanism similar to pluggy 712260429 | |
752770133 | https://github.com/simonw/datasette/issues/983#issuecomment-752770133 | https://api.github.com/repos/simonw/datasette/issues/983 | MDEyOklzc3VlQ29tbWVudDc1Mjc3MDEzMw== | simonw 9599 | 2020-12-30T21:53:45Z | 2020-12-30T21:54:22Z | OWNER | FixMyStreet inlines some JavaScript, and it's always a good idea to copy what they're doing when it comes to web performance: https://github.com/mysociety/fixmystreet/blob/23e9564b58a86b783ce47f3c0bf837cbd4fe7282/templates/web/base/common_header_tags.html#L19-L25 Note `var fixmystreet=fixmystreet||{};` which is shorter - https://twitter.com/dracos/status/1344399909794045954 | {"total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0} | JavaScript plugin hooks mechanism similar to pluggy 712260429 | |
752770488 | https://github.com/simonw/datasette/issues/983#issuecomment-752770488 | https://api.github.com/repos/simonw/datasette/issues/983 | MDEyOklzc3VlQ29tbWVudDc1Mjc3MDQ4OA== | simonw 9599 | 2020-12-30T21:55:35Z | 2020-12-30T21:58:26Z | OWNER | This one minifies to 241: ```javascript var datasette = datasette || {}; datasette.plugins = (() => { var registry = {}; return { register: (hook, fn, parameters) => { if (!registry[hook]) { registry[hook] = []; } registry[hook].push([fn, parameters]); }, call: (hook, args) => { args = args || {}; var results = []; (registry[hook] || []).forEach(([fn, parameters]) => { /* Call with the correct arguments */ var result = fn.apply(fn, parameters.map(parameter => args[parameter])); if (result) { results.push(result); } }); return results; } }; })(); ``` `var datasette=datasette||{};datasette.plugins=(()=>{var a={};return{register:(t,r,e)=>{a[t]||(a[t]=[]),a[t].push([r,e])},call:(t,r)=>{r=r||{};var e=[];return(a[t]||[]).forEach(([a,t])=>{var s=a.apply(a,t.map(a=>r[a]));s&&e.push(s)}),e}}})();` | {"total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0} | JavaScript plugin hooks mechanism similar to pluggy 712260429 | |
752773508 | https://github.com/simonw/datasette/issues/983#issuecomment-752773508 | https://api.github.com/repos/simonw/datasette/issues/983 | MDEyOklzc3VlQ29tbWVudDc1Mjc3MzUwOA== | simonw 9599 | 2020-12-30T22:10:08Z | 2020-12-30T22:11:34Z | OWNER | https://twitter.com/dracos/status/1344402639476424706 points out that plugins returning 0 will be ignored. This should probably check for `result !== undefined` instead - knocks the size up to 250. | {"total_count": 0, "+1": 0, "-1": 0, "laugh": 0, "hooray": 0, "confused": 0, "heart": 0, "rocket": 0, "eyes": 0} | JavaScript plugin hooks mechanism similar to pluggy 712260429 |
Advanced export
JSON shape: default, array, newline-delimited, object
CREATE TABLE [issue_comments] ( [html_url] TEXT, [issue_url] TEXT, [id] INTEGER PRIMARY KEY, [node_id] TEXT, [user] INTEGER REFERENCES [users]([id]), [created_at] TEXT, [updated_at] TEXT, [author_association] TEXT, [body] TEXT, [reactions] TEXT, [issue] INTEGER REFERENCES [issues]([id]) , [performed_via_github_app] TEXT); CREATE INDEX [idx_issue_comments_issue] ON [issue_comments] ([issue]); CREATE INDEX [idx_issue_comments_user] ON [issue_comments] ([user]);