# use tabs ('hard tabs'), not spaces ('soft tabs')... xD~ # just hook up the 'cleanup' and/or 'fin' events, under the 'process' as well als 'global'.. ;-) # this will be emitted on ANY form of exit (signals, exception, regular, ...)! :-) # if more DYNAMIC behavior should happen when loading modules (without that "nothing" will happen due to CACHE), use 'module.exports = function _() { ... }'. # see 'utility/main.js' and 'network/main.js' # and see 'test.js/dynamic-require.js'! :-) # see 'DEFAULT_RENDER_SUBTRACT' or '.subtract' option in "String.render()"!!! this is important for objects/arrays/..!!! # you should count an extra int in your for()-loops to push values to an array.. asking .length every time respective [].push() may be much more inefficient... right? # loading pages: some routines.. v.a. use 'page.load()' w/ optional target, otherwise the default 'CONFIG[TARGET]' respektive 'window.target'!! # function accepts .extension, but also w/o, to try to load all of the same name w/ extensions from CONFIG[LOAD]! # ajax() will (see _localize [beneath _process]) try to LOCALIZE pages (by CONFIG[LANGUAGE]), see also CONFIG[LOCALIZE]!!! !! # NOW pls use 'handleLink(_callback, _href, _event, _target, _throw)'!!!!! :-)) # maybe better use 'core/MAP' for multi-dimensional "arrays" (..fields ;-), without nesting these arrays (so also possible w/ strings, or uint8array, etc..! ;-) # OR alternatively set '(Array|TypedArray).dimensions' and use the functions in these list types.... maybe more efficient access than w/ proxy, mainly @ typed-array.. # alle "core/ITEM"-kinder muessen im constructor zuerst "super(_options)" legen.. und natuelrich als argument auch "_options" haben.. # die werden dann direkt umgesetzt - SOFERN ein key im objekt implementiert ist.. alle, welche nicht, liegen in '.MISSING{}' # vorteile des ganzen: (a) "this.options" haelt nur tatsaechliche optionen.. (b) "morph()"-objekt-klassen-conversion ist einfach (nur .options angeben ;-) # this.options.MISSING{} fuer spaetere morph() etc. w/o implementation... sammelt sich dort alles, wird aber auch immer wieder probiert ^_^ # beachte: console.{log,info,..}() uses u.a. 'String.printf()', so all real '%' chars need to be escaped ('\\%')!! xD~ !!! # 3dscript-engine: simply use 'Uint8Array' für *alle* speicher-anforderungen (w/ String, ..)! # use BigInt.from() instead of 'BigInt(..)'!!!!! AND in general it'd be better to use 'parseNumber()' (etc.) instead of 'Number()', so _radix can vary l8rs, inter alia... # Number.from() is the same... atm "unused", but maybe in the future..!?! # pls use new 'Object.isObject()' instead of (typeof == object && !== null)! ;-) # AND: 'Object.null()' is also GREAT! ;-) # BTW: Object...assign() is a bit different from the original.. and Object...merge() merges objects and their sub(-sub(-..)) elements.. ;-) # pls use new 'Number.isNumber()' instead of 'typeof', wg. w/ '.isNumber'; .. und 'isNumeric()' sowie '[BigInt.]isBigInt()' # `grep -r typeof * | grep "'number'"` # und fuer bigint UND number: 'isNumeric()' (oder gar 'String...isNumeric()') # use 'String.isString()' instead of (typeof == string && .length > 0)! ;-) # `grep -r typeof * | grep "'string'" | grep '\.length'` # and 2nd arg can be boolean or NOW NEW: integer w/ min length! # same holds for Array.isArray() and Uint8Array.isUint8Array(); .. # bitte immer 'static create()'.. mehr möglichkeiten, sei's blosz singleton... ;-) # `grep -r 'new ' * | grep -v 'Array(' | grep -v 'Date(' | grep -v 'Error(' | grep -v 'new this'` # @ 'static create()' => ueberall bitte NICHT MEHR 'return new $Class(..)', sondern 'return new this(...)'!! # je nachdem faellt dann redundanz bei gleichen routinen in vererbten klassen weg... ^_^ # instead of checking _radix_alphabet and call (string).toRadix/toString(), just use '.encode()' or '.decode()'! # it'll automatically check 'String.encoding[]'... ;-) # TODO: what 'bout 'ext/utility.js'::checkEncoding()!?? # SHOULD MAYBE directly use 'alphabet(..)'!? otherwise we'd to do it manually... je naCHDEM. # is not capable of alphabets atm.. btw. :-) # use 'process.stdio[0-2]{,std*}' instead of 'process.std{in,out,err}'... that makes later scaling more practicable (e.g. internal relays or so)... ^_^ # haeufig.. wo _callback, auch (true) zulassen, damit async, trotz keiner callback-function "per se"... ;-) # d.h. if(_callback) und darin erst vor eigentlicher feuerung if(typeof _callback === 'function')! ^_^ # circular dependencies: einfach einen stack der verwendeten items verwenden (gerne auch in funktionen ..._stack), und jew. indexOf(item)-check! ;-) # dann werden die auf gleicher ebene o.ae. nicht stoeren... nur im selben "pfad"! ;-D # 'path.check(_string, _single_name)' to reduce the characters to ascii (32 - 126) [see 'String..cut()'] (and maybe even '/' from/to '\\', depending on os); # always use the ansi-functions in here.. alternatively please "close" the sequences with \0.. that's to make it easier to parse ansi escape sequences..!! ;-) # bei (gerade tty/ansi..) farben immer fuer zufaellige folgende moeglichkeiten: [ true, '', 'random', 'random4', 'random8', 'random24' ]... ^_^ # => MASSIV EVENTs BENUTZEN.. und BITTE MOEGLICHST IMMER _event-OBJEKTE NUTZEN, statt grosze arguments-anzahl..!!! # so dass quasi "alles gut vernetzt ist" und alle kausalitaet schon ein wenig walten kann..! ;-) # dazu habe ich ein eigenes 'core/event'.. use that, pls! ;-) # it's also in the 'global/window' object. :-D # siehe 'web/html/HTMLElement.js': # vor allem bitte auch NUR '.{set,unset,get,has,..}Style()' verwenden, da diese ueber (eigene @ window..) events so ueberwachbar werden.. (unter anderem das)! # 'window.emit()' nutzen, um unabhaengig selbst nochmal extra events nutzen zu koennen (browser's dispatch*() etc. "ersetzen" quasi ;-) # WHEN(!) 'utility/jsoff' is ready, maybe you should use it as an alternative to JSON.. is somewhat better.. BUT COULD eventually be a bit slower... dunno. # you can/should simply use 'Animation' ('ext/animation.js'); ...! ^_^ # BROWSER: always use 'Pointer Events' instead of 'touch' or 'mouse'.. (even if 'window.touch' exists ;-) ... # browser support available? see 'window.pointer'..! ;-) # maybe we want to design some own 'Pointer Events' then!? lohnt sich ned, eh??! x)~ # if not supported: if(window.touch) .. and don't forget: touch devices like smartphones can also have a mouse attached to them..... ^_^ # "dblclick" sowie "click" werden simuliert durch 'web/pointer.js' - also auch bei touch/pen/mouse/.. wo regulaer nicht nativ verfuegbares event.. # einfach "pointer.on(...)". siehe dazu auch "CONFIG.THRESHOLD_MS" sowie "CONFIG.DBLCLICK"! :-) # ebenso das HALTEN (dann loslassen) mit pointer in den events 'on' sowie 'off' (see CONFIG[THRESHOLD_{PX,MS}]!)! # fuer laengen nutze (bis implementiere w/ _length in enumerables as .getIndex) 'getIndex()' bzw. auch teilweise 'getLength()'.. # das wird automatisch negative werte vom ende aus zurueck zaehlen, bspw., aber auch MODULO (%) angewandt auf werte groeszer als die _length.. ;-) # in 'return x()', you "should" set an (error.)TYPE string, so it'll be easier to automatically "debug" exceptions (then the scripts know what type of error caused what ;-) # unfortunately neglected both on x(); but it'd much better to do it from now on.. (it's also much prettier with colorized elements ;-) # 2nd x()-param can be .TYPE STRING, but also an object where you can ALSO put '.type', beneath more attributes for the resulting error object (all will be visible @ output) @ BROWSER: bedenke CONFIG.TARGET, und dass alle "echten inhalte" dort hinein kommen sollten... siehe auch 'lib.js/browser/web/ext/a.js'... hier btw XMLHttpRequest() zum laden der files..! ^_^ # dazu gibt's v.a. auch noch 'window.target' => liefert das jew. in CONFIG.TARGET per string die id suchende element.. und sucht im dom immer dann neu, wenn CONFIG.TARGET veraendert wurde # bedenke 'dblclick' zum -öffnen.. auch: kein 'onclick=' mehr! @ BROWSER: bitte moeglichst viele styles css-sache sein lassen, sowie '.classList.{add,remove,..}()'!! ..viel besser, in './css/' definieren als in den klassen selbst zu stylen...! ;-) @ BROWSER / HTMLElement etc... statt in den events die .parentNode abzufragen, bitte direkt die jew. 'get()' mitsamt optionalem .parentNode-traverse implementieren # dadurch wird die verwendung 'transparent'... und macht's alles einfacher - siehe 'web/ext/help.js' (w/ 'help' in HTMLElement[.js] ;-) ... # aber bitte nur durchreichen, NICHT die eigentlich abgefragten children adaptieren.. das schafft nur unnoetig overhead und probleme, etc... # bei 'web/pointer'-events simply use '_event.find()'.. see 'web/pointer.js' @ function emit().. ;-) @ BROWSER: now there's 'window.on/once/off/emit/..()' etc.. EVENT ('core/event.js') is inherited, so massively use it (e.g. HTMLElement.setStyle(), etc..), pls..!! :-D # do NOT (callback).call(..) or .apply(..)! .. it's better to not hard-bind these functions to any object. the current context will do it # either use 'self' references outside the callback for the inside, or use anonymous functions.. # events will do so, too. # i'd prefer to specify _callback always as first argument... # have to update my code lines for this, sometimes... TODO. # PHP scripts for more server-side support... please use the global function '[cgi.]php(_url, _callback)' (@ 'cgi.js').. will include these checks(!!!): # ONLY use php-scripts if "{CONFIG.,GLOBAL.}CGI" is a (non-empty!) directory path string or (true)... # ALL PHP-scripts which are used by the library should set a header (["X-PHP"] = phpversion()); ... # makes a check possible, if php is really installed and script has been executed correctly... ;-) # PLEASE obey any SECURITY issues in your scripts... mostly it's about correct path handling, etc.. # a helping "template" can be found in 'lib.js/BROWSER/web/page.js' @ 'Page._ip()' # as pointer out: 'cgi.js' => exactly the same with 'X-CGI' and 'cgi()' (i partially want to run e.g. shell-scripts as cgi's ;-) # callbacks auch in jedem fehler-falle aufrufen (mit angepassten arguments); # dadurch können die prozesse richtig "terminiert" werden (ihre erwarung); # wenn ein "abbruch" der regulaeren funktionalitaet, so bevorzuge ich ein event-emit w/ (null) als erstes argument.. # BESTENFALLS *JEDES* event als LETZTEN parameter 'this' jeweils... hm!?! # AM BESTEN IMMER NUR *EIN* argument.. wo alles enthalten liegt, inkl. {this}, {error}, etc.. # sowohl fuer events/callbacks als auch alle funktionen.. SOLLTE zumindest so sein m.e., aber das habe ich selbst noch nichtmal ganz geregelt bis jetzt.. # global 'alphabet()' function is to prepare for numeric's (radix conversion etc.), String.prototype.alphabet() is generally used for NON-numeric cases # global one (in 'ext/alphabet.js') will throw errors in some cases (e.g. result alphabet string is too short).. string's one will NOT. :-) # BTW: it rumors that ++i is a BIT more efficient than i++.. xD~ # STATT '(!)== EOL' bitte immer '.at(i, EOL)' oder '.{starts,ends}With(EOL)'!!! denn: EOL kann mehr als nur ein character lang sein... # bedenke das fuer alles moegliche... auch gleich fuer 'path.sep' bestenfalls. # BTW: speziell fuer EOL nutze evtl. direkt 'String.prototype.isEOL(_index)'; das beachtet ALLE (4x atm) newline-typen. # ... sonst muesste erstmal 'String.prototype.eol()'-conversion. # debugging code is easier with '[console.]testing()' .. it'll also call process.exit() afterwards, so you'll only see the real debug values as last output. # you can even use an internal counter (with data buffer), so that after (n) calls the debug output is created (before process.exit())! .. just look at 'shared/console.js'! :-D # if you wish to show numbers with changing radix value, see 'radix()' [w/ CONFIG[RADIX_{RANDOM,RANGE,INTERVAL}]!]! # by using this, ALL shown numbers will have the same radix at the same time... so there' no chaos, only symmetry..! ;-D # just use 'on("radix", ..', the callback function is '(_new, _old)'! ;-) # depends on 'CONFIG["RADIX_INTERVAL"]'.. if not an integer > 0, nothing should happen... # check 'radix.enabled' before; if(false), no periodical updates [but you can use this function nevertheless - w/ true as first arg changes current value ;-]; # beachte 'sonderfall': 'radix(null)'! ;-D # BTW: meinen copyright-vermerk erhaelt man stets mit der globalen 'COPYRIGHT()' funktion [evtl auch die parameter von interest?]... # see also 'document.measure()' and '(HTMLElement).measure()'... jfyi. ^_^ # it'd be really cool if you choose getopt-'short' "'?'" for '--help'.. ;-) # don't forget: if using *both* Math.floor/ceil/..() and Math.abs() => 'Math.*(Math.abs(..))'. right (the order)!?? # if you want to QUOTE your strings, use '(string).quote()'.. # the quote-string (optional argument) will also escape any occurrence of this quote-string.. # w/o string-argument the quote-sign is chosen by counting the amount of default quote signs.. less occurrence makes it then. # bestenfalls JEDE FUNKTION OPTIONAL MIT {} OPTIONS STATT VIELER ARGUMENTS...?! # use 'const options = Object.assign(... arguments)'..!! ^_^ # don't check for RADIX w/ (typeof == number) or so.. use '[numeric.]isRadix(_value, _limited = false)'!! # this also checks for suitable alphabet strings (after uniq at least two characters left..!) # working with unicodes (e.g. "🌟" w/ .unicodeLength == 1 and .length == 2): # just regularily use '(string).length' for loops, which re-assemble strings, or such things, etc.. # there you can 'res += str.at(i)' or 'res += str[i]'.. # also worx w/ 'res += String.fromCharCode(str.codePointAt(i))'... # but when creating strings @ utf or so, you can also use 'String.fromCodePoint()'; is the same as .fromCharCode() with values < 256.. ;-) # see also 'test.js/string/unicode*.js'.. so we can say, regular usage is totally unicode compatible! :-D # if somewhere smth. like 'options{ colors: true }' or so, use the global 'COLORS' boolean variable (see './global.js')! ^_^ # if you want to change the 'colormap', do it in 'String.COLORMAP'... 'String.colormap' (used anywhere) is being dynamically generated... # (.. because 'TypedArray' to all types of 'em) # BUT: the values are an array(2), to combine foreground/text and background colors... # for localized number/tostring output, now '.toText()' also support integer or {min,max}-integers to define '.toLocaleString({ {minimum,maximum}FractionDigits })'!! ;-) # so somehow no need to use '.toFixed()', too. ^_^ # to find an object's prototypes, or to compare if it's an instance of smth., just use 'Object.was(_item, ... _args)'! :-) # the ..._args are optional strings, to directly compare.. if none, result will be an array/object type (w/ [] and string-keys, too) # safe numbers (@ 'ext/numeric'): use 'numberTooHigh()' and 'adaptNumber()'... ;-) # you should note (all in String.prototype): '.less', '.LESS', '.textLength' ... ^_^ # during library intialization, '__INIT' is true, after that, it's false.. # used because some modules are not loaded by default, depending on 'BROWSER' boolean.. after init, these 'main.js' will load all of it's sub modules.. # all sub-classes from 'core/LIST' contain '.INIT', too... so the order of settings options on creation is no longer important (if real initialization is done l8rs ;-) # bei status-ausgaben am besten 'ansi.status()' nutzen [basiert auf 'ansi.cursor.column(0); ansi.clear.line();' ;-] # erstmal weil so direkt die jew. aktuelle zeile je status neu ersetzt wird # zweitens, weil auch die laenge gegen console-breite gecheckt wird, also abgeschnitten, falls zu lang [damit der refresh immer bleibt ;-] .. # drittens, weil direkt '[String.]printf()' integriert ist.. fuer farbige abbildung der params, etc.. ;-) # BTW: (null) oder int(>0) als zweiten parameter wird entsprechende eol() ausgeben.. praktisch fuer's ende der .status()-ausgabe.. ;-) # soll eben beschriebes 'ansi.status()' direkt eine richtige progress-bar sein!?? => dann nutze direkt 'console.progress()'! # whereas (null) as first argument is like { end: true }.. # if you work with links in the BROWSER, you should use 'Uniform.toHTML()'.. that makes prettier links! ;-) # if you want to check for a minimum key length somewhere, use 'keyLength(_string, _throw)' w/ CONFIG.KEYS every time.. # .. so this way we hold a global value for the minimum key length all over the library or the applications which use this lib.. ;-) # to generate random passwords, just use 'crypt.createRandomPassword(_length = KEYS)'.. # see 'lib.js/ext/crypt.js' [all 'crypt', NOT 'crypto'.. ;-] ... # use 'process.warn(... _printf)' instead of 'process.emitWarning()'.. pls. :)~ # if searching for object members, you can use 'Object.prototype.lookUp()'; # the 'core/' classes (and children) HIDE members w/ '_'-prefix (proxy ;)~ //