Can anyone tell me how the haschanged operator works?

Folks, I am interested in capturing all changes to a wiki, in the current session, this includes installing plugins, tiddlers and executing bookmarklets on a given wiki.

I would like to understand the mechanism used by haschanged which seems to involve the change count mechanism, and also wonder how that works.

I want to see if I can easily identify the installed or edited tiddlers regardless of where they come from or are contained within to capture ONLY these changes.

  • I suspect I may need to enhance this mechanism or extend the filter to achieve this.

See my browser storage plugin for example:

https://btheado.github.io/tw-browser-storage/#%24%3A%2Fplugins%2Fbtheado%2FBrowserStorage%2FTiddlersChangedSinceStartup:%24%3A%2Fplugins%2Fbtheado%2FBrowserStorage%2FTiddlersChangedSinceStartup%20%24%3A%2Fplugins%2Fbtheado%2FBrowserStorage%2FTiddlersLoadedFromBrowserStorage

I’m using haschanged AND also only matching tiddlers which meet the BrowserStorage save filter

The documentation for how to use it seems pretty straightforward, so I’m assuming that you’re asking about how it’s implemented underneath the covers. If so, read on.

I’m answering not from deep experience but from some poking around the source code.

One central module is $:/core/modules/wiki. This has all sorts of code for wiki-wide activities. One property it maintains is changeCount. It serves as a hash-map between wiki titles and the count of changes for those titles since the wiki was loaded. This object is instantiated when needed if it’s not already present. That happens in multiple places in the source code. When the wiki’s enqueueTiddlerEvent method is called, the count for that tiddler is incremented if it already exists, and created and set to 1 if it doesn’t already exist.

The haschanged operator simply queries that hashmap for the current tiddler, and if it has a value greater than 0, it’s listed as changed. The places that query this value seem to be scattered around the code, but the changes seem to be limited to enqueueTiddlerEvent… if I haven’t missed something.

2 Likes

Thanks @btheado I have being led to this as well. In this case I am not using browser storage but thanks for reminding me about it.

  • When applying changes to a wiki, to subsequently package, already using local storage I may need to keep this in mind.

Since I install things on an empty.html including plugins to build such a packages I have sofar come up with the following package filter, once I make my changes.
[haschanges[]] [plugin-type[plugin]] -[[$:core]] -[prefix[$/temp]] -[prefix[$/state]] -[[$:/StoryList]] -[[$:/HistoryList]] -[[$:/Import]] [[$:/support tiddler]]

  • I will first install this from a bookmarklet.
  • I will include a support tiddler, that opens by default with access to a few tools such as the import button.

The whole process can be made even easier by including the above support tiddler in the saved packages, but designed to be used when importing the package I generate. This tiddler can again force itself to open once.

  • I may include $:/StoryList with it’s list set to the tiddler I want to open after install.

Thanks @Scott_Sauyet that is helpful.

As you can see from my above filter tiddlers installed by bookmarklet can be seen, but not plugin tiddlers so I need to include them.

  • I think I have the changes covered with the above filter now including plugins, but I would be helpful to know any other exceptions, but exceptions can be hard to find.

Are you saying [haschanged[]] is not returning plugins for you? I find if I drop a new plugin onto tiddlywiki.com and import it, then that plugin tiddler is in the haschanged output.

Yes you are correct::+1: Until the wiki is saved and reloaded.

I think I erroneously checked for $/core not $:/plugin tiddlers, it is the same with bookmarklets, combined with the fact if you do save and reload there is no install date on plugins and the other tiddlers, they have their last “older” creation and modified dates, from when they were bookmarked.